mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 18:42:56 +08:00
Merge branch 'master' into hitobject-pooling-base
This commit is contained in:
commit
2840fd0f8f
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.1110.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.1111.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -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 System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -54,12 +55,77 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHoldNoteMissAfterNextObjectStartTime()
|
||||||
|
{
|
||||||
|
var objects = new List<ManiaHitObject>
|
||||||
|
{
|
||||||
|
new HoldNote
|
||||||
|
{
|
||||||
|
StartTime = 1000,
|
||||||
|
EndTime = 1010,
|
||||||
|
},
|
||||||
|
new HoldNote
|
||||||
|
{
|
||||||
|
StartTime = 1020,
|
||||||
|
EndTime = 1030
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
performTest(objects, new List<ReplayFrame>());
|
||||||
|
|
||||||
|
addJudgementAssert(objects[0], HitResult.IgnoreHit);
|
||||||
|
addJudgementAssert(objects[1], HitResult.IgnoreHit);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHoldNoteReleasedHitAfterNextObjectStartTime()
|
||||||
|
{
|
||||||
|
var objects = new List<ManiaHitObject>
|
||||||
|
{
|
||||||
|
new HoldNote
|
||||||
|
{
|
||||||
|
StartTime = 1000,
|
||||||
|
EndTime = 1010,
|
||||||
|
},
|
||||||
|
new HoldNote
|
||||||
|
{
|
||||||
|
StartTime = 1020,
|
||||||
|
EndTime = 1030
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var frames = new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(1000, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(1030),
|
||||||
|
new ManiaReplayFrame(1040, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(1050)
|
||||||
|
};
|
||||||
|
|
||||||
|
performTest(objects, frames);
|
||||||
|
|
||||||
|
addJudgementAssert(objects[0], HitResult.IgnoreHit);
|
||||||
|
addJudgementAssert("first head", () => ((HoldNote)objects[0]).Head, HitResult.Perfect);
|
||||||
|
addJudgementAssert("first tail", () => ((HoldNote)objects[0]).Tail, HitResult.Perfect);
|
||||||
|
|
||||||
|
addJudgementAssert(objects[1], HitResult.IgnoreHit);
|
||||||
|
addJudgementAssert("second head", () => ((HoldNote)objects[1]).Head, HitResult.Great);
|
||||||
|
addJudgementAssert("second tail", () => ((HoldNote)objects[1]).Tail, HitResult.Perfect);
|
||||||
|
}
|
||||||
|
|
||||||
private void addJudgementAssert(ManiaHitObject hitObject, HitResult result)
|
private void addJudgementAssert(ManiaHitObject hitObject, HitResult result)
|
||||||
{
|
{
|
||||||
AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}",
|
AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}",
|
||||||
() => judgementResults.Single(r => r.HitObject == hitObject).Type == result);
|
() => judgementResults.Single(r => r.HitObject == hitObject).Type == result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addJudgementAssert(string name, Func<ManiaHitObject> hitObject, HitResult result)
|
||||||
|
{
|
||||||
|
AddAssert($"{name} judgement is {result}",
|
||||||
|
() => judgementResults.Single(r => r.HitObject == hitObject()).Type == result);
|
||||||
|
}
|
||||||
|
|
||||||
private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset)
|
private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset)
|
||||||
{
|
{
|
||||||
AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}",
|
AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}",
|
||||||
|
@ -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.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
@ -44,9 +43,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
/// <param name="hitObject">The <see cref="HitObject"/> that was hit.</param>
|
/// <param name="hitObject">The <see cref="HitObject"/> that was hit.</param>
|
||||||
public void HandleHit(DrawableHitObject hitObject)
|
public void HandleHit(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset))
|
|
||||||
throw new InvalidOperationException($"A {hitObject} was hit before it became hittable!");
|
|
||||||
|
|
||||||
foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime))
|
foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime))
|
||||||
{
|
{
|
||||||
if (obj.Judged)
|
if (obj.Judged)
|
||||||
|
@ -125,6 +125,9 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
if (!enabled) return null;
|
if (!enabled) return null;
|
||||||
|
|
||||||
|
if (component is OsuSkinComponent osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody)
|
||||||
|
return null;
|
||||||
|
|
||||||
return new OsuSpriteText
|
return new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = identifier,
|
Text = identifier,
|
||||||
|
@ -27,17 +27,23 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
foreach (var d in drawables)
|
foreach (var d in drawables)
|
||||||
d.ApplyCustomUpdateState += applyFadeInAdjustment;
|
{
|
||||||
|
d.HitObjectApplied += applyFadeInAdjustment;
|
||||||
|
applyFadeInAdjustment(d);
|
||||||
|
}
|
||||||
|
|
||||||
base.ApplyToDrawableHitObjects(drawables);
|
base.ApplyToDrawableHitObjects(drawables);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyFadeInAdjustment(DrawableHitObject hitObject, ArmedState state)
|
private void applyFadeInAdjustment(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
if (!(hitObject is DrawableOsuHitObject d))
|
if (!(hitObject is DrawableOsuHitObject d))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d.HitObject.TimeFadeIn = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
d.HitObject.TimeFadeIn = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
||||||
|
|
||||||
|
foreach (var nested in d.NestedHitObjects)
|
||||||
|
applyFadeInAdjustment(nested);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double lastSliderHeadFadeOutStartTime;
|
private double lastSliderHeadFadeOutStartTime;
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneKiaiHitExplosion : TaikoSkinnableTestScene
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestKiaiHits()
|
||||||
|
{
|
||||||
|
AddStep("rim hit", () => SetContents(() => getContentFor(createHit(HitType.Rim))));
|
||||||
|
AddStep("centre hit", () => SetContents(() => getContentFor(createHit(HitType.Centre))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable getContentFor(DrawableTestHit hit)
|
||||||
|
{
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = new KiaiHitExplosion(hit, hit.HitObject.Type)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private DrawableTestHit createHit(HitType type) => new DrawableTestHit(new Hit { StartTime = Time.Current, Type = type });
|
||||||
|
}
|
||||||
|
}
|
@ -114,6 +114,14 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
case TaikoSkinComponents.TaikoExplosionKiai:
|
||||||
|
// suppress the default kiai explosion if the skin brings its own sprites.
|
||||||
|
// the drawable needs to expire as soon as possible to avoid accumulating empty drawables on the playfield.
|
||||||
|
if (hasExplosion.Value)
|
||||||
|
return Drawable.Empty().With(d => d.LifetimeEnd = double.MinValue);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
case TaikoSkinComponents.Scroller:
|
case TaikoSkinComponents.Scroller:
|
||||||
if (GetTexture("taiko-slider") != null)
|
if (GetTexture("taiko-slider") != null)
|
||||||
return new LegacyTaikoScroller();
|
return new LegacyTaikoScroller();
|
||||||
|
@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
TaikoExplosionMiss,
|
TaikoExplosionMiss,
|
||||||
TaikoExplosionOk,
|
TaikoExplosionOk,
|
||||||
TaikoExplosionGreat,
|
TaikoExplosionGreat,
|
||||||
|
TaikoExplosionKiai,
|
||||||
Scroller,
|
Scroller,
|
||||||
Mascot,
|
Mascot,
|
||||||
}
|
}
|
||||||
|
64
osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs
Normal file
64
osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// 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 osuTK;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Effects;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
|
{
|
||||||
|
public class DefaultKiaiHitExplosion : CircularContainer
|
||||||
|
{
|
||||||
|
public override bool RemoveWhenNotAlive => true;
|
||||||
|
|
||||||
|
private readonly HitType type;
|
||||||
|
|
||||||
|
public DefaultKiaiHitExplosion(HitType type)
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Blending = BlendingParameters.Additive;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
Alpha = 0.25f;
|
||||||
|
|
||||||
|
Children = new[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Colour = type == HitType.Rim ? colours.BlueDarker : colours.PinkDarker,
|
||||||
|
Radius = 60,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
this.ScaleTo(new Vector2(1, 3f), 500, Easing.OutQuint);
|
||||||
|
this.FadeOut(250);
|
||||||
|
|
||||||
|
Expire(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,71 +1,47 @@
|
|||||||
// 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 osuTK;
|
|
||||||
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.Framework.Graphics.Effects;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class KiaiHitExplosion : CircularContainer
|
public class KiaiHitExplosion : Container
|
||||||
{
|
{
|
||||||
public override bool RemoveWhenNotAlive => true;
|
public override bool RemoveWhenNotAlive => true;
|
||||||
|
|
||||||
|
[Cached(typeof(DrawableHitObject))]
|
||||||
public readonly DrawableHitObject JudgedObject;
|
public readonly DrawableHitObject JudgedObject;
|
||||||
private readonly HitType type;
|
|
||||||
|
|
||||||
public KiaiHitExplosion(DrawableHitObject judgedObject, HitType type)
|
private readonly HitType hitType;
|
||||||
|
|
||||||
|
private SkinnableDrawable skinnable;
|
||||||
|
|
||||||
|
public override double LifetimeStart => skinnable.Drawable.LifetimeStart;
|
||||||
|
|
||||||
|
public override double LifetimeEnd => skinnable.Drawable.LifetimeEnd;
|
||||||
|
|
||||||
|
public KiaiHitExplosion(DrawableHitObject judgedObject, HitType hitType)
|
||||||
{
|
{
|
||||||
JudgedObject = judgedObject;
|
JudgedObject = judgedObject;
|
||||||
this.type = type;
|
this.hitType = hitType;
|
||||||
|
|
||||||
Anchor = Anchor.CentreLeft;
|
Anchor = Anchor.CentreLeft;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Size = new Vector2(TaikoHitObject.DEFAULT_SIZE, 1);
|
Size = new Vector2(TaikoHitObject.DEFAULT_SIZE, 1);
|
||||||
|
|
||||||
Blending = BlendingParameters.Additive;
|
|
||||||
|
|
||||||
Masking = true;
|
|
||||||
Alpha = 0.25f;
|
|
||||||
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Alpha = 0,
|
|
||||||
AlwaysPresent = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load()
|
||||||
{
|
{
|
||||||
EdgeEffect = new EdgeEffectParameters
|
Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType));
|
||||||
{
|
|
||||||
Type = EdgeEffectType.Glow,
|
|
||||||
Colour = type == HitType.Rim ? colours.BlueDarker : colours.PinkDarker,
|
|
||||||
Radius = 60,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
this.ScaleTo(new Vector2(1, 3f), 500, Easing.OutQuint);
|
|
||||||
this.FadeOut(250);
|
|
||||||
|
|
||||||
Expire(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
{
|
{
|
||||||
public class LegacyBeatmapDecoder : LegacyDecoder<Beatmap>
|
public class LegacyBeatmapDecoder : LegacyDecoder<Beatmap>
|
||||||
{
|
{
|
||||||
public const int LATEST_VERSION = 14;
|
|
||||||
|
|
||||||
private Beatmap beatmap;
|
private Beatmap beatmap;
|
||||||
|
|
||||||
private ConvertHitObjectParser parser;
|
private ConvertHitObjectParser parser;
|
||||||
|
@ -16,6 +16,8 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
public abstract class LegacyDecoder<T> : Decoder<T>
|
public abstract class LegacyDecoder<T> : Decoder<T>
|
||||||
where T : new()
|
where T : new()
|
||||||
{
|
{
|
||||||
|
public const int LATEST_VERSION = 14;
|
||||||
|
|
||||||
protected readonly int FormatVersion;
|
protected readonly int FormatVersion;
|
||||||
|
|
||||||
protected LegacyDecoder(int version)
|
protected LegacyDecoder(int version)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps.Legacy;
|
using osu.Game.Beatmaps.Legacy;
|
||||||
@ -23,15 +24,15 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
private readonly Dictionary<string, string> variables = new Dictionary<string, string>();
|
private readonly Dictionary<string, string> variables = new Dictionary<string, string>();
|
||||||
|
|
||||||
public LegacyStoryboardDecoder()
|
public LegacyStoryboardDecoder(int version = LATEST_VERSION)
|
||||||
: base(0)
|
: base(version)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Register()
|
public static void Register()
|
||||||
{
|
{
|
||||||
// note that this isn't completely correct
|
// note that this isn't completely correct
|
||||||
AddDecoder<Storyboard>(@"osu file format v", m => new LegacyStoryboardDecoder());
|
AddDecoder<Storyboard>(@"osu file format v", m => new LegacyStoryboardDecoder(Parsing.ParseInt(m.Split('v').Last())));
|
||||||
AddDecoder<Storyboard>(@"[Events]", m => new LegacyStoryboardDecoder());
|
AddDecoder<Storyboard>(@"[Events]", m => new LegacyStoryboardDecoder());
|
||||||
SetFallbackDecoder<Storyboard>(() => new LegacyStoryboardDecoder());
|
SetFallbackDecoder<Storyboard>(() => new LegacyStoryboardDecoder());
|
||||||
}
|
}
|
||||||
@ -133,6 +134,11 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
var y = Parsing.ParseFloat(split[5], Parsing.MAX_COORDINATE_VALUE);
|
var y = Parsing.ParseFloat(split[5], Parsing.MAX_COORDINATE_VALUE);
|
||||||
var frameCount = Parsing.ParseInt(split[6]);
|
var frameCount = Parsing.ParseInt(split[6]);
|
||||||
var frameDelay = Parsing.ParseDouble(split[7]);
|
var frameDelay = Parsing.ParseDouble(split[7]);
|
||||||
|
|
||||||
|
if (FormatVersion < 6)
|
||||||
|
// this is random as hell but taken straight from osu-stable.
|
||||||
|
frameDelay = Math.Round(0.015 * frameDelay) * 1.186 * (1000 / 60f);
|
||||||
|
|
||||||
var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever;
|
var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever;
|
||||||
storyboardSprite = new StoryboardAnimation(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType);
|
storyboardSprite = new StoryboardAnimation(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType);
|
||||||
storyboard.GetLayer(layer).Add(storyboardSprite);
|
storyboard.GetLayer(layer).Add(storyboardSprite);
|
||||||
|
@ -681,7 +681,6 @@ namespace osu.Game
|
|||||||
|
|
||||||
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
||||||
loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true);
|
loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true);
|
||||||
loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener(), topMostOverlayContent.Add);
|
|
||||||
|
|
||||||
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer<APIUserMostPlayedBeatmap>
|
public class PaginatedMostPlayedBeatmapContainer : PaginatedContainer<APIUserMostPlayedBeatmap>
|
||||||
{
|
{
|
||||||
public PaginatedMostPlayedBeatmapContainer(Bindable<User> user)
|
public PaginatedMostPlayedBeatmapContainer(Bindable<User> user)
|
||||||
: base(user, "Most Played Beatmaps", "No records. :(")
|
: base(user, "Most Played Beatmaps", "No records. :(", CounterVisibilityState.AlwaysVisible)
|
||||||
{
|
{
|
||||||
ItemsPerPage = 5;
|
ItemsPerPage = 5;
|
||||||
}
|
}
|
||||||
@ -27,6 +27,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
ItemsContainer.Direction = FillDirection.Vertical;
|
ItemsContainer.Direction = FillDirection.Vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override int GetCount(User user) => user.BeatmapPlaycountsCount;
|
||||||
|
|
||||||
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest() =>
|
protected override APIRequest<List<APIUserMostPlayedBeatmap>> CreateRequest() =>
|
||||||
new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage);
|
new GetUserMostPlayedBeatmapsRequest(User.Value.Id, VisiblePages++, ItemsPerPage);
|
||||||
|
|
||||||
|
@ -27,8 +27,16 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
[Cached(typeof(DrawableHitObject))]
|
[Cached(typeof(DrawableHitObject))]
|
||||||
public abstract class DrawableHitObject : SkinReloadableDrawable
|
public abstract class DrawableHitObject : SkinReloadableDrawable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked after this <see cref="DrawableHitObject"/>'s applied <see cref="HitObject"/> has had its defaults applied.
|
||||||
|
/// </summary>
|
||||||
public event Action<DrawableHitObject> DefaultsApplied;
|
public event Action<DrawableHitObject> DefaultsApplied;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked after a <see cref="HitObject"/> has been applied to this <see cref="DrawableHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<DrawableHitObject> HitObjectApplied;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="HitObject"/> currently represented by this <see cref="DrawableHitObject"/>.
|
/// The <see cref="HitObject"/> currently represented by this <see cref="DrawableHitObject"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -221,6 +229,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
HitObject.DefaultsApplied += onDefaultsApplied;
|
HitObject.DefaultsApplied += onDefaultsApplied;
|
||||||
|
|
||||||
OnApply(hitObject);
|
OnApply(hitObject);
|
||||||
|
HitObjectApplied?.Invoke(this);
|
||||||
|
|
||||||
// If not loaded, the state update happens in LoadComplete(). Otherwise, the update is scheduled to allow for lifetime updates.
|
// If not loaded, the state update happens in LoadComplete(). Otherwise, the update is scheduled to allow for lifetime updates.
|
||||||
if (IsLoaded)
|
if (IsLoaded)
|
||||||
|
@ -144,6 +144,9 @@ namespace osu.Game.Users
|
|||||||
[JsonProperty(@"scores_first_count")]
|
[JsonProperty(@"scores_first_count")]
|
||||||
public int ScoresFirstCount;
|
public int ScoresFirstCount;
|
||||||
|
|
||||||
|
[JsonProperty(@"beatmap_playcounts_count")]
|
||||||
|
public int BeatmapPlaycountsCount;
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private string[] playstyle
|
private string[] playstyle
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,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.1110.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.1111.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.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.1110.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.1111.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||||
@ -88,7 +88,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.1110.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.1111.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