mirror of
https://github.com/ppy/osu.git
synced 2025-03-18 06:27:18 +08:00
Merge remote-tracking branch 'upstream/master' into consistent-mod-button-sounds
This commit is contained in:
commit
e88965b433
@ -60,7 +60,7 @@
|
||||
<Reference Include="Java.Interop" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.830.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.903.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.830.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -82,11 +82,11 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
remove { }
|
||||
}
|
||||
|
||||
public Drawable GetDrawableComponent(string componentName)
|
||||
public Drawable GetDrawableComponent(ISkinComponent component)
|
||||
{
|
||||
switch (componentName)
|
||||
switch (component.LookupName)
|
||||
{
|
||||
case "Play/Catch/fruit-catcher-idle":
|
||||
case "Gameplay/Catch/fruit-catcher-idle":
|
||||
return new CatcherCustomSkin();
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Catch
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
||||
|
||||
public const string SHORT_NAME = "fruits";
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.Z, CatchAction.MoveLeft),
|
||||
@ -117,7 +119,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
|
||||
public override string Description => "osu!catch";
|
||||
|
||||
public override string ShortName => "fruits";
|
||||
public override string ShortName => SHORT_NAME;
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
|
||||
|
||||
|
19
osu.Game.Rulesets.Catch/CatchSkinComponent.cs
Normal file
19
osu.Game.Rulesets.Catch/CatchSkinComponent.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public class CatchSkinComponent : GameplaySkinComponent<CatchSkinComponents>
|
||||
{
|
||||
public CatchSkinComponent(CatchSkinComponents component)
|
||||
: base(component)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string RulesetPrefix => "catch"; // todo: use CatchRuleset.SHORT_NAME;
|
||||
|
||||
protected override string ComponentName => Component.ToString().ToLower();
|
||||
}
|
||||
}
|
9
osu.Game.Rulesets.Catch/CatchSkinComponents.cs
Normal file
9
osu.Game.Rulesets.Catch/CatchSkinComponents.cs
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public enum CatchSkinComponents
|
||||
{
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new SkinnableSprite(@"Play/Catch/fruit-catcher-idle")
|
||||
InternalChild = new SkinnableSprite("Gameplay/catch/fruit-catcher-idle")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
|
@ -11,7 +11,9 @@ using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Mania.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Mania.Mods;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
{
|
||||
@ -32,12 +34,15 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
|
||||
HitWindows hitWindows = new ManiaHitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||
|
||||
return new ManiaDifficultyAttributes
|
||||
{
|
||||
StarRating = difficultyValue(skills) * star_scaling_factor,
|
||||
Mods = mods,
|
||||
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
|
||||
GreatHitWindow = (int)(hitWindows.Great / 2) / clockRate,
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ namespace osu.Game.Rulesets.Mania
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
||||
|
||||
public const string SHORT_NAME = "mania";
|
||||
|
||||
public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this);
|
||||
|
||||
public override IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods)
|
||||
@ -163,7 +165,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
public override string Description => "osu!mania";
|
||||
|
||||
public override string ShortName => "mania";
|
||||
public override string ShortName => SHORT_NAME;
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania };
|
||||
|
||||
|
19
osu.Game.Rulesets.Mania/ManiaSkinComponent.cs
Normal file
19
osu.Game.Rulesets.Mania/ManiaSkinComponent.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaSkinComponent : GameplaySkinComponent<ManiaSkinComponents>
|
||||
{
|
||||
public ManiaSkinComponent(ManiaSkinComponents component)
|
||||
: base(component)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME;
|
||||
|
||||
protected override string ComponentName => Component.ToString().ToLower();
|
||||
}
|
||||
}
|
9
osu.Game.Rulesets.Mania/ManiaSkinComponents.cs
Normal file
9
osu.Game.Rulesets.Mania/ManiaSkinComponents.cs
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public enum ManiaSkinComponents
|
||||
{
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
@ -209,6 +210,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
Debug.Assert(HitObject.HitWindows != null);
|
||||
|
||||
// Factor in the release lenience
|
||||
timeOffset /= release_window_lenience;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -52,6 +53,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
Debug.Assert(HitObject.HitWindows != null);
|
||||
|
||||
if (!userTriggered)
|
||||
{
|
||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||
|
@ -5,6 +5,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
@ -99,5 +100,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
||||
}
|
||||
|
||||
public override Judgement CreateJudgement() => new HoldNoteJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
@ -12,5 +13,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
||||
public class HoldNoteTick : ManiaHitObject
|
||||
{
|
||||
public override Judgement CreateJudgement() => new HoldNoteTickJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
@ -24,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
|
||||
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
|
||||
new DrawableOsuJudgement(new JudgementResult(null) { Type = result }, null)
|
||||
new DrawableOsuJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -13,8 +14,10 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
var drawableHitObject = base.CreateDrawableHitCircle(circle, auto);
|
||||
|
||||
Scheduler.AddDelayed(() => drawableHitObject.TriggerJudgement(),
|
||||
drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.HalfWindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current);
|
||||
Debug.Assert(drawableHitObject.HitObject.HitWindows != null);
|
||||
|
||||
double delay = drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.HalfWindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current;
|
||||
Scheduler.AddDelayed(() => drawableHitObject.TriggerJudgement(), delay);
|
||||
|
||||
return drawableHitObject;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public Drawable GetDrawableComponent(string componentName)
|
||||
public Drawable GetDrawableComponent(ISkinComponent component)
|
||||
{
|
||||
if (!enabled) return null;
|
||||
|
||||
|
@ -9,6 +9,7 @@ using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Osu.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
@ -34,8 +35,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
||||
|
||||
HitWindows hitWindows = new OsuHitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||
|
||||
// Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||
double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate;
|
||||
double hitWindowGreat = (int)(hitWindows.Great / 2) / clockRate;
|
||||
double preempt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
||||
|
||||
int maxCombo = beatmap.HitObjects.Count;
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Judgements
|
||||
{
|
||||
@ -9,8 +10,8 @@ namespace osu.Game.Rulesets.Osu.Judgements
|
||||
{
|
||||
public ComboResult ComboType;
|
||||
|
||||
public OsuJudgementResult(Judgement judgement)
|
||||
: base(judgement)
|
||||
public OsuJudgementResult(HitObject hitObject, Judgement judgement)
|
||||
: base(hitObject, judgement)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get("Play/osu/blinds-panel");
|
||||
Texture = textures.Get("Gameplay/osu/blinds-panel");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
@ -38,7 +39,12 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit)
|
||||
continue;
|
||||
|
||||
requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime);
|
||||
if (osuHit is DrawableHitCircle && osuHit.IsHovered)
|
||||
{
|
||||
Debug.Assert(osuHit.HitObject.HitWindows != null);
|
||||
requiresHit |= osuHit.HitObject.HitWindows.CanBeHit(relativetime);
|
||||
}
|
||||
|
||||
requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Child = new SkinnableDrawable("Play/osu/followpoint", _ => new Container
|
||||
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new Container
|
||||
{
|
||||
Masking = true,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -58,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
return true;
|
||||
},
|
||||
},
|
||||
mainContent = new SkinnableDrawable("Play/osu/hitcircle", _ => new MainCirclePiece(HitObject.IndexInCurrentCombo)),
|
||||
mainContent = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.HitCircle), _ => new MainCirclePiece(HitObject.IndexInCurrentCombo)),
|
||||
ApproachCircle = new ApproachCircle
|
||||
{
|
||||
Alpha = 0,
|
||||
@ -87,6 +88,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
Debug.Assert(HitObject.HitWindows != null);
|
||||
|
||||
if (!userTriggered)
|
||||
{
|
||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||
@ -119,6 +122,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
protected override void UpdateStateTransforms(ArmedState state)
|
||||
{
|
||||
Debug.Assert(HitObject.HitWindows != null);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Idle:
|
||||
|
@ -41,6 +41,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
|
||||
|
||||
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement);
|
||||
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
Blending = BlendingParameters.Additive;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon
|
||||
InternalChild = scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Icon = FontAwesome.Solid.ChevronRight,
|
||||
|
@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
InternalChild = scaleContainer = new SkinnableDrawable("Play/osu/sliderscorepoint", _ => new CircularContainer
|
||||
InternalChild = scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
Origin = Anchor.Centre,
|
||||
|
@ -31,13 +31,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
private class SkinnableApproachCircle : SkinnableSprite
|
||||
{
|
||||
public SkinnableApproachCircle()
|
||||
: base("Play/osu/approachcircle")
|
||||
: base("Gameplay/osu/approachcircle")
|
||||
{
|
||||
}
|
||||
|
||||
protected override Drawable CreateDefault(string name)
|
||||
protected override Drawable CreateDefault(ISkinComponent component)
|
||||
{
|
||||
var drawable = base.CreateDefault(name);
|
||||
var drawable = base.CreateDefault(component);
|
||||
|
||||
// account for the sprite being used for the default approach circle being taken from stable,
|
||||
// when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = textures.Get(@"Play/osu/disc"),
|
||||
Texture = textures.Get(@"Gameplay/osu/disc"),
|
||||
},
|
||||
new TrianglesPiece
|
||||
{
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
@ -20,12 +19,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
Blending = BlendingParameters.Additive;
|
||||
Alpha = 0;
|
||||
|
||||
Child = new SkinnableDrawable("Play/osu/hitcircle-explode", _ => new TrianglesPiece
|
||||
Child = new TrianglesPiece
|
||||
{
|
||||
Blending = BlendingParameters.Additive,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.2f,
|
||||
}, s => s.GetTexture("Play/osu/hitcircle") == null);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osuTK;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
Blending = BlendingParameters.Additive;
|
||||
Alpha = 0;
|
||||
|
||||
Child = new SkinnableDrawable("Play/osu/hitcircle-flash", name => new CircularContainer
|
||||
Child = new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}, s => s.GetTexture("Play/osu/hitcircle") == null);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
@ -22,14 +21,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Child = new SkinnableDrawable("Play/osu/ring-glow", name => new Sprite
|
||||
Child = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = textures.Get(name),
|
||||
Texture = textures.Get("Gameplay/osu/ring-glow"),
|
||||
Blending = BlendingParameters.Additive,
|
||||
Alpha = 0.5f
|
||||
}, s => s.GetTexture("Play/osu/hitcircle") == null);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SkinnableDrawable("Play/osu/number-glow", name => new CircularContainer
|
||||
new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
Origin = Anchor.Centre,
|
||||
@ -41,8 +41,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
Colour = Color4.White.Opacity(0.5f),
|
||||
},
|
||||
Child = new Box()
|
||||
}, s => s.GetTexture("Play/osu/hitcircle") == null),
|
||||
number = new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText
|
||||
},
|
||||
number = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.Numeric.With(size: 40),
|
||||
UseFullGlyphHeight = false,
|
||||
|
@ -6,7 +6,6 @@ using osu.Framework.Graphics.Containers;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
{
|
||||
@ -19,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
InternalChild = new SkinnableDrawable("Play/osu/hitcircleoverlay", _ => new Container
|
||||
InternalChild = new Container
|
||||
{
|
||||
Masking = true,
|
||||
CornerRadius = Size.X / 2,
|
||||
@ -35,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
Anchor = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
Child = new SkinnableDrawable("Play/osu/sliderfollowcircle", _ => new DefaultFollowCircle()),
|
||||
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()),
|
||||
},
|
||||
new CircularContainer
|
||||
{
|
||||
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new SkinnableDrawable("Play/osu/sliderball", _ => new DefaultSliderBall()),
|
||||
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -229,5 +229,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples;
|
||||
|
||||
public override Judgement CreateJudgement() => new OsuJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects
|
||||
@ -30,5 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
}
|
||||
|
||||
public override Judgement CreateJudgement() => new OsuJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects
|
||||
@ -31,5 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
}
|
||||
|
||||
public override Judgement CreateJudgement() => new OsuJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ namespace osu.Game.Rulesets.Osu
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap);
|
||||
|
||||
public const string SHORT_NAME = "osu";
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.Z, OsuAction.LeftButton),
|
||||
@ -161,7 +163,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
|
||||
public override string Description => "osu!";
|
||||
|
||||
public override string ShortName => "osu";
|
||||
public override string ShortName => SHORT_NAME;
|
||||
|
||||
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
||||
|
||||
|
19
osu.Game.Rulesets.Osu/OsuSkinComponent.cs
Normal file
19
osu.Game.Rulesets.Osu/OsuSkinComponent.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
public class OsuSkinComponent : GameplaySkinComponent<OsuSkinComponents>
|
||||
{
|
||||
public OsuSkinComponent(OsuSkinComponents component)
|
||||
: base(component)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string RulesetPrefix => OsuRuleset.SHORT_NAME;
|
||||
|
||||
protected override string ComponentName => Component.ToString().ToLower();
|
||||
}
|
||||
}
|
18
osu.Game.Rulesets.Osu/OsuSkinComponents.cs
Normal file
18
osu.Game.Rulesets.Osu/OsuSkinComponents.cs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
public enum OsuSkinComponents
|
||||
{
|
||||
HitCircle,
|
||||
FollowPoint,
|
||||
Cursor,
|
||||
SliderScorePoint,
|
||||
ApproachCircle,
|
||||
ReverseArrow,
|
||||
HitCircleText,
|
||||
SliderFollowCircle,
|
||||
SliderBall
|
||||
}
|
||||
}
|
@ -6,9 +6,11 @@ using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -36,6 +38,8 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
/// </summary>
|
||||
private readonly double reactionTime;
|
||||
|
||||
private readonly HitWindows defaultHitWindows;
|
||||
|
||||
/// <summary>
|
||||
/// What easing to use when moving between hitobjects
|
||||
/// </summary>
|
||||
@ -50,6 +54,9 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
{
|
||||
// Already superhuman, but still somewhat realistic
|
||||
reactionTime = ApplyModsToRate(100);
|
||||
|
||||
defaultHitWindows = new OsuHitWindows();
|
||||
defaultHitWindows.SetDifficulty(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -91,21 +98,49 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
{
|
||||
double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime;
|
||||
|
||||
HitWindows hitWindows = null;
|
||||
|
||||
switch (h)
|
||||
{
|
||||
case HitCircle hitCircle:
|
||||
hitWindows = hitCircle.HitWindows;
|
||||
break;
|
||||
|
||||
case Slider slider:
|
||||
hitWindows = slider.TailCircle.HitWindows;
|
||||
break;
|
||||
|
||||
case Spinner _:
|
||||
hitWindows = defaultHitWindows;
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.Assert(hitWindows != null);
|
||||
|
||||
// Make the cursor stay at a hitObject as long as possible (mainly for autopilot).
|
||||
if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Miss) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50)
|
||||
if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Miss) > endTime + hitWindows.HalfWindowFor(HitResult.Meh) + 50)
|
||||
{
|
||||
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
|
||||
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
|
||||
if (!(prev is Spinner) && h.StartTime - endTime < 1000)
|
||||
AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
|
||||
|
||||
if (!(h is Spinner))
|
||||
AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
|
||||
}
|
||||
else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50)
|
||||
else if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Meh) > endTime + hitWindows.HalfWindowFor(HitResult.Meh) + 50)
|
||||
{
|
||||
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
|
||||
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
|
||||
if (!(prev is Spinner) && h.StartTime - endTime < 1000)
|
||||
AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
|
||||
|
||||
if (!(h is Spinner))
|
||||
AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
|
||||
}
|
||||
else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Good) > endTime + h.HitWindows.HalfWindowFor(HitResult.Good) + 50)
|
||||
else if (h.StartTime - hitWindows.HalfWindowFor(HitResult.Good) > endTime + hitWindows.HalfWindowFor(HitResult.Good) + 50)
|
||||
{
|
||||
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
|
||||
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
|
||||
if (!(prev is Spinner) && h.StartTime - endTime < 1000)
|
||||
AddFrameToReplay(new OsuReplayFrame(endTime + hitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
|
||||
|
||||
if (!(h is Spinner))
|
||||
AddFrameToReplay(new OsuReplayFrame(h.StartTime - hitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement);
|
||||
protected override JudgementResult CreateResult(HitObject hitObject, Judgement judgement) => new OsuJudgementResult(hitObject, judgement);
|
||||
|
||||
public override HitWindows CreateHitWindows() => new OsuHitWindows();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText
|
||||
new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.Numeric.With(size: 40),
|
||||
UseFullGlyphHeight = false,
|
||||
|
@ -55,14 +55,17 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
hasHitCircle = new Lazy<bool>(() => source.GetTexture("hitcircle") != null);
|
||||
}
|
||||
|
||||
public Drawable GetDrawableComponent(string componentName)
|
||||
public Drawable GetDrawableComponent(ISkinComponent component)
|
||||
{
|
||||
switch (componentName)
|
||||
{
|
||||
case "Play/osu/sliderfollowcircle":
|
||||
return this.GetAnimation(componentName, true, true);
|
||||
if (!(component is OsuSkinComponent osuComponent))
|
||||
return null;
|
||||
|
||||
case "Play/osu/sliderball":
|
||||
switch (osuComponent.Component)
|
||||
{
|
||||
case OsuSkinComponents.SliderFollowCircle:
|
||||
return this.GetAnimation("sliderfollowcircle", true, true);
|
||||
|
||||
case OsuSkinComponents.SliderBall:
|
||||
var sliderBallContent = this.GetAnimation("sliderb", true, true, "");
|
||||
|
||||
if (sliderBallContent != null)
|
||||
@ -80,20 +83,19 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
|
||||
return null;
|
||||
|
||||
case "Play/osu/hitcircle":
|
||||
case OsuSkinComponents.HitCircle:
|
||||
if (hasHitCircle.Value)
|
||||
return new LegacyMainCirclePiece();
|
||||
|
||||
return null;
|
||||
|
||||
case "Play/osu/cursor":
|
||||
case OsuSkinComponents.Cursor:
|
||||
if (source.GetTexture("cursor") != null)
|
||||
return new LegacyCursor();
|
||||
|
||||
return null;
|
||||
|
||||
case "Play/osu/number-text":
|
||||
|
||||
case OsuSkinComponents.HitCircleText:
|
||||
string font = GetValue<SkinConfiguration, string>(config => config.HitCircleFont);
|
||||
var overlap = GetValue<SkinConfiguration, float>(config => config.HitCircleOverlap);
|
||||
|
||||
@ -115,7 +117,13 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample);
|
||||
|
||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration
|
||||
=> configuration.Value is TConfiguration conf ? query.Invoke(conf) : source.GetValue(query);
|
||||
{
|
||||
TValue val;
|
||||
if (configuration.Value is TConfiguration conf && (val = query.Invoke(conf)) != null)
|
||||
return val;
|
||||
|
||||
return source.GetValue(query);
|
||||
}
|
||||
|
||||
private bool hasFont(string fontName) => source.GetTexture($"{fontName}-0") != null;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Child = scaleTarget = new SkinnableDrawable("Play/osu/cursor", _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling)
|
||||
Child = scaleTarget = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling)
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
|
74
osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs
Normal file
74
osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
public class TestSceneSwellJudgements : PlayerTestScene
|
||||
{
|
||||
protected new TestPlayer Player => (TestPlayer)base.Player;
|
||||
|
||||
public TestSceneSwellJudgements()
|
||||
: base(new TaikoRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestZeroTickTimeOffsets()
|
||||
{
|
||||
AddUntilStep("gameplay finished", () => Player.ScoreProcessor.HasCompleted);
|
||||
AddAssert("all tick offsets are 0", () => Player.Results.Where(r => r.Judgement is TaikoSwellTickJudgement).All(r => r.TimeOffset == 0));
|
||||
}
|
||||
|
||||
protected override bool Autoplay => true;
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var beatmap = new Beatmap<TaikoHitObject>
|
||||
{
|
||||
BeatmapInfo = { Ruleset = new TaikoRuleset().RulesetInfo },
|
||||
HitObjects =
|
||||
{
|
||||
new Swell
|
||||
{
|
||||
StartTime = 1000,
|
||||
Duration = 1000,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer();
|
||||
|
||||
protected class TestPlayer : Player
|
||||
{
|
||||
public readonly List<JudgementResult> Results = new List<JudgementResult>();
|
||||
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
|
||||
public TestPlayer()
|
||||
: base(false, false)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
ScoreProcessor.NewJudgement += r => Results.Add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
|
||||
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
|
||||
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement()) { Type = hitResult });
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult });
|
||||
}
|
||||
|
||||
private void addStrongHitJudgement(bool kiai)
|
||||
@ -159,13 +159,13 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
|
||||
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
|
||||
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement()) { Type = hitResult });
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new TaikoStrongJudgement()) { Type = HitResult.Great });
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = hitResult });
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new HitObject(), new TaikoStrongJudgement()) { Type = HitResult.Great });
|
||||
}
|
||||
|
||||
private void addMissJudgement()
|
||||
{
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new TaikoJudgement()) { Type = HitResult.Miss });
|
||||
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new HitObject(), new TaikoJudgement()) { Type = HitResult.Miss });
|
||||
}
|
||||
|
||||
private void addBarLine(bool major, double delay = scroll_time)
|
||||
|
@ -8,6 +8,7 @@ using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Taiko.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Taiko.Mods;
|
||||
@ -29,12 +30,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new TaikoDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
|
||||
HitWindows hitWindows = new TaikoHitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||
|
||||
return new TaikoDifficultyAttributes
|
||||
{
|
||||
StarRating = skills.Single().DifficultyValue() * star_scaling_factor,
|
||||
Mods = mods,
|
||||
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
|
||||
GreatHitWindow = (int)(hitWindows.Great / 2) / clockRate,
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Hit),
|
||||
Skills = skills
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
@ -34,6 +35,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
Debug.Assert(HitObject.HitWindows != null);
|
||||
|
||||
if (!userTriggered)
|
||||
{
|
||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||
@ -94,6 +97,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
|
||||
protected override void UpdateStateTransforms(ArmedState state)
|
||||
{
|
||||
Debug.Assert(HitObject.HitWindows != null);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Idle:
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
@ -14,7 +15,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
}
|
||||
|
||||
public void TriggerResult(HitResult type) => ApplyResult(r => r.Type = type);
|
||||
protected override void UpdateInitialTransforms() => this.FadeOut();
|
||||
|
||||
public void TriggerResult(HitResult type)
|
||||
{
|
||||
HitObject.StartTime = Time.Current;
|
||||
ApplyResult(r => r.Type = type);
|
||||
}
|
||||
|
||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ using System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects
|
||||
@ -86,5 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
}
|
||||
|
||||
public override Judgement CreateJudgement() => new TaikoDrumRollJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects
|
||||
@ -25,5 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
public double HitWindow => TickSpacing / 2;
|
||||
|
||||
public override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects
|
||||
@ -9,5 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
public class StrongHitObject : TaikoHitObject
|
||||
{
|
||||
public override Judgement CreateJudgement() => new TaikoStrongJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects
|
||||
@ -33,5 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
}
|
||||
|
||||
public override Judgement CreateJudgement() => new TaikoSwellJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects
|
||||
@ -9,5 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
public class SwellTick : TaikoHitObject
|
||||
{
|
||||
public override Judgement CreateJudgement() => new TaikoSwellTickJudgement();
|
||||
|
||||
protected override HitWindows CreateHitWindows() => null;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Taiko
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IWorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableTaikoRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
|
||||
|
||||
public const string SHORT_NAME = "taiko";
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.MouseLeft, TaikoAction.LeftCentre),
|
||||
@ -116,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
public override string Description => "osu!taiko";
|
||||
|
||||
public override string ShortName => "taiko";
|
||||
public override string ShortName => SHORT_NAME;
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetTaiko };
|
||||
|
||||
|
19
osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs
Normal file
19
osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
public class TaikoSkinComponent : GameplaySkinComponent<TaikoSkinComponents>
|
||||
{
|
||||
public TaikoSkinComponent(TaikoSkinComponents component)
|
||||
: base(component)
|
||||
{
|
||||
}
|
||||
|
||||
protected override string RulesetPrefix => TaikoRuleset.SHORT_NAME;
|
||||
|
||||
protected override string ComponentName => Component.ToString().ToLower();
|
||||
}
|
||||
}
|
9
osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs
Normal file
9
osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
public enum TaikoSkinComponents
|
||||
{
|
||||
}
|
||||
}
|
@ -132,10 +132,10 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures, OsuColour colours)
|
||||
{
|
||||
rim.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer");
|
||||
rimHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-outer-hit");
|
||||
centre.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner");
|
||||
centreHit.Texture = textures.Get(@"Play/Taiko/taiko-drum-inner-hit");
|
||||
rim.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer");
|
||||
rimHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer-hit");
|
||||
centre.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner");
|
||||
centreHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner-hit");
|
||||
|
||||
rimHit.Colour = colours.Blue;
|
||||
centreHit.Colour = colours.Pink;
|
||||
|
@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
private void newJudgement(double offset = 0)
|
||||
{
|
||||
var judgement = new JudgementResult(new Judgement())
|
||||
var judgement = new JudgementResult(new HitObject(), new Judgement())
|
||||
{
|
||||
TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset,
|
||||
Type = HitResult.Perfect,
|
||||
|
@ -137,8 +137,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public new Drawable Drawable => base.Drawable;
|
||||
|
||||
public ExposedSkinnableDrawable(string name, Func<string, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit)
|
||||
: base(name, defaultImplementation, allowFallback, confineMode)
|
||||
public ExposedSkinnableDrawable(string name, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit)
|
||||
: base(new TestSkinComponent(name), defaultImplementation, allowFallback, confineMode)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -206,8 +206,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
public new Drawable Drawable => base.Drawable;
|
||||
public int SkinChangedCount { get; private set; }
|
||||
|
||||
public SkinConsumer(string name, Func<string, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null)
|
||||
: base(name, defaultImplementation, allowFallback)
|
||||
public SkinConsumer(string name, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null)
|
||||
: base(new TestSkinComponent(name), defaultImplementation, allowFallback)
|
||||
{
|
||||
}
|
||||
|
||||
@ -243,8 +243,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Drawable GetDrawableComponent(string componentName) =>
|
||||
componentName == "available"
|
||||
public Drawable GetDrawableComponent(ISkinComponent componentName) =>
|
||||
componentName.LookupName == "available"
|
||||
? new DrawWidthBox
|
||||
{
|
||||
Colour = Color4.Yellow,
|
||||
@ -261,7 +261,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
private class SecondarySource : ISkin
|
||||
{
|
||||
public Drawable GetDrawableComponent(string componentName) => new SecondarySourceBox();
|
||||
public Drawable GetDrawableComponent(ISkinComponent componentName) => new SecondarySourceBox();
|
||||
|
||||
public Texture GetTexture(string componentName) => throw new NotImplementedException();
|
||||
|
||||
@ -272,7 +272,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
private class SkinSourceContainer : Container, ISkin
|
||||
{
|
||||
public Drawable GetDrawableComponent(string componentName) => new BaseSourceBox();
|
||||
public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox();
|
||||
|
||||
public Texture GetTexture(string componentName) => throw new NotImplementedException();
|
||||
|
||||
@ -280,5 +280,19 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private class TestSkinComponent : ISkinComponent
|
||||
{
|
||||
private readonly string name;
|
||||
|
||||
public TestSkinComponent(string name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public string ComponentGroup => string.Empty;
|
||||
|
||||
public string LookupName => name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +176,8 @@ namespace osu.Game.Tests.Visual.Online
|
||||
HasVideo = true,
|
||||
HasStoryboard = true,
|
||||
Covers = new BeatmapSetOnlineCovers(),
|
||||
Language = new BeatmapSetOnlineLanguage { Id = 3, Name = "English" },
|
||||
Genre = new BeatmapSetOnlineGenre { Id = 4, Name = "Rock" },
|
||||
},
|
||||
Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() },
|
||||
Beatmaps = new List<BeatmapInfo>
|
||||
|
246
osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs
Normal file
246
osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs
Normal file
@ -0,0 +1,246 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Overlays.Profile.Sections.Kudosu;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneKudosuHistory : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(DrawableKudosuHistoryItem),
|
||||
};
|
||||
|
||||
private readonly Box background;
|
||||
|
||||
public TestSceneKudosuHistory()
|
||||
{
|
||||
FillFlowContainer<DrawableKudosuHistoryItem> content;
|
||||
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
background = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
content = new FillFlowContainer<DrawableKudosuHistoryItem>
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Width = 0.7f,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
}
|
||||
});
|
||||
|
||||
items.ForEach(t => content.Add(new DrawableKudosuHistoryItem(t)));
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
background.Colour = colours.GreySeafoam;
|
||||
}
|
||||
|
||||
private readonly IEnumerable<APIKudosuHistory> items = new[]
|
||||
{
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 10,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2011, 11, 11)),
|
||||
Source = KudosuSource.DenyKudosu,
|
||||
Action = KudosuAction.Reset,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 1",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username1",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 5,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2012, 10, 11)),
|
||||
Source = KudosuSource.Forum,
|
||||
Action = KudosuAction.Give,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 2",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username2",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 8,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2013, 9, 11)),
|
||||
Source = KudosuSource.Forum,
|
||||
Action = KudosuAction.Reset,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 3",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username3",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 7,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2014, 8, 11)),
|
||||
Source = KudosuSource.Forum,
|
||||
Action = KudosuAction.Revoke,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 4",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username4",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 100,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2015, 7, 11)),
|
||||
Source = KudosuSource.Vote,
|
||||
Action = KudosuAction.Give,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 5",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username5",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 20,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)),
|
||||
Source = KudosuSource.Vote,
|
||||
Action = KudosuAction.Reset,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 6",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username6",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 11,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)),
|
||||
Source = KudosuSource.AllowKudosu,
|
||||
Action = KudosuAction.Give,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 7",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username7",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 24,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2014, 6, 11)),
|
||||
Source = KudosuSource.Delete,
|
||||
Action = KudosuAction.Reset,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 8",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username8",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 12,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2016, 6, 11)),
|
||||
Source = KudosuSource.Restore,
|
||||
Action = KudosuAction.Give,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 9",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username9",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 2,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2012, 6, 11)),
|
||||
Source = KudosuSource.Recalculate,
|
||||
Action = KudosuAction.Give,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 10",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username10",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
},
|
||||
new APIKudosuHistory
|
||||
{
|
||||
Amount = 32,
|
||||
CreatedAt = new DateTimeOffset(new DateTime(2019, 8, 11)),
|
||||
Source = KudosuSource.Recalculate,
|
||||
Action = KudosuAction.Reset,
|
||||
Post = new APIKudosuHistory.ModdingPost
|
||||
{
|
||||
Title = @"Random post 11",
|
||||
Url = @"https://osu.ppy.sh/b/1234",
|
||||
},
|
||||
Giver = new APIKudosuHistory.KudosuGiver
|
||||
{
|
||||
Username = @"Username11",
|
||||
Url = @"https://osu.ppy.sh/u/1234"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
@ -25,6 +26,11 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
{
|
||||
private readonly NowPlayingOverlay np;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(BeatSyncedContainer)
|
||||
};
|
||||
|
||||
[Cached]
|
||||
private MusicController musicController = new MusicController();
|
||||
|
||||
@ -154,7 +160,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
if (timingPoints[timingPoints.Count - 1] == current)
|
||||
return current;
|
||||
|
||||
return timingPoints[timingPoints.IndexOf(current) + 1];
|
||||
int index = timingPoints.IndexOf(current); // -1 means that this is a "default beat"
|
||||
|
||||
return index == -1 ? current : timingPoints[index + 1];
|
||||
}
|
||||
|
||||
private int calculateBeatCount(TimingControlPoint current)
|
||||
|
@ -75,6 +75,28 @@ namespace osu.Game.Beatmaps
|
||||
/// The availability of this beatmap set.
|
||||
/// </summary>
|
||||
public BeatmapSetOnlineAvailability Availability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The song genre of this beatmap set.
|
||||
/// </summary>
|
||||
public BeatmapSetOnlineGenre Genre { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The song language of this beatmap set.
|
||||
/// </summary>
|
||||
public BeatmapSetOnlineLanguage Language { get; set; }
|
||||
}
|
||||
|
||||
public class BeatmapSetOnlineGenre
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class BeatmapSetOnlineLanguage
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class BeatmapSetOnlineCovers
|
||||
|
@ -33,23 +33,46 @@ namespace osu.Game.Graphics.Containers
|
||||
/// </summary>
|
||||
public double TimeSinceLastBeat { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default length of a beat in milliseconds. Used whenever there is no beatmap or track playing.
|
||||
/// </summary>
|
||||
private const double default_beat_length = 60000.0 / 60.0;
|
||||
|
||||
private TimingControlPoint defaultTiming;
|
||||
private EffectControlPoint defaultEffect;
|
||||
private TrackAmplitudes defaultAmplitudes;
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.BeatmapLoaded) return;
|
||||
Track track = null;
|
||||
IBeatmap beatmap = null;
|
||||
|
||||
var track = Beatmap.Value.Track;
|
||||
var beatmap = Beatmap.Value.Beatmap;
|
||||
double currentTrackTime;
|
||||
TimingControlPoint timingPoint;
|
||||
EffectControlPoint effectPoint;
|
||||
|
||||
if (track == null || beatmap == null)
|
||||
return;
|
||||
if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded)
|
||||
{
|
||||
track = Beatmap.Value.Track;
|
||||
beatmap = Beatmap.Value.Beatmap;
|
||||
}
|
||||
|
||||
double currentTrackTime = track.Length > 0 ? track.CurrentTime + EarlyActivationMilliseconds : Clock.CurrentTime;
|
||||
if (track != null && beatmap != null && track.IsRunning)
|
||||
{
|
||||
currentTrackTime = track.Length > 0 ? track.CurrentTime + EarlyActivationMilliseconds : Clock.CurrentTime;
|
||||
|
||||
TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime);
|
||||
EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime);
|
||||
timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime);
|
||||
effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime);
|
||||
|
||||
if (timingPoint.BeatLength == 0)
|
||||
return;
|
||||
if (timingPoint.BeatLength == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentTrackTime = Clock.CurrentTime;
|
||||
timingPoint = defaultTiming;
|
||||
effectPoint = defaultEffect;
|
||||
}
|
||||
|
||||
int beatIndex = (int)((currentTrackTime - timingPoint.Time) / timingPoint.BeatLength);
|
||||
|
||||
@ -67,7 +90,7 @@ namespace osu.Game.Graphics.Containers
|
||||
return;
|
||||
|
||||
using (BeginDelayedSequence(-TimeSinceLastBeat, true))
|
||||
OnNewBeat(beatIndex, timingPoint, effectPoint, track.CurrentAmplitudes);
|
||||
OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? defaultAmplitudes);
|
||||
|
||||
lastBeat = beatIndex;
|
||||
lastTimingPoint = timingPoint;
|
||||
@ -77,6 +100,28 @@ namespace osu.Game.Graphics.Containers
|
||||
private void load(IBindable<WorkingBeatmap> beatmap)
|
||||
{
|
||||
Beatmap.BindTo(beatmap);
|
||||
|
||||
defaultTiming = new TimingControlPoint
|
||||
{
|
||||
BeatLength = default_beat_length,
|
||||
AutoGenerated = true,
|
||||
Time = 0
|
||||
};
|
||||
|
||||
defaultEffect = new EffectControlPoint
|
||||
{
|
||||
Time = 0,
|
||||
AutoGenerated = true,
|
||||
KiaiMode = false,
|
||||
OmitFirstBarLine = false
|
||||
};
|
||||
|
||||
defaultAmplitudes = new TrackAmplitudes
|
||||
{
|
||||
FrequencyAmplitudes = new float[256],
|
||||
LeftChannel = 0,
|
||||
RightChannel = 0
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
|
21
osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs
Normal file
21
osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetUserKudosuHistoryRequest : PaginatedAPIRequest<List<APIKudosuHistory>>
|
||||
{
|
||||
private readonly long userId;
|
||||
|
||||
public GetUserKudosuHistoryRequest(long userId, int page = 0, int itemsPerPage = 5)
|
||||
: base(page, itemsPerPage)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
protected override string Target => $"users/{userId}/kudosu";
|
||||
}
|
||||
}
|
@ -69,6 +69,12 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
[JsonProperty(@"availability")]
|
||||
private BeatmapSetOnlineAvailability availability { get; set; }
|
||||
|
||||
[JsonProperty(@"genre")]
|
||||
private BeatmapSetOnlineGenre genre { get; set; }
|
||||
|
||||
[JsonProperty(@"language")]
|
||||
private BeatmapSetOnlineLanguage language { get; set; }
|
||||
|
||||
[JsonProperty(@"beatmaps")]
|
||||
private IEnumerable<APIBeatmap> beatmaps { get; set; }
|
||||
|
||||
@ -95,6 +101,8 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
LastUpdated = lastUpdated,
|
||||
Availability = availability,
|
||||
HasFavourited = hasFavourited,
|
||||
Genre = genre,
|
||||
Language = language
|
||||
},
|
||||
Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(),
|
||||
};
|
||||
|
83
osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs
Normal file
83
osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIKudosuHistory
|
||||
{
|
||||
[JsonProperty("created_at")]
|
||||
public DateTimeOffset CreatedAt;
|
||||
|
||||
[JsonProperty("amount")]
|
||||
public int Amount;
|
||||
|
||||
[JsonProperty("post")]
|
||||
public ModdingPost Post;
|
||||
|
||||
public class ModdingPost
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url;
|
||||
|
||||
[JsonProperty("title")]
|
||||
public string Title;
|
||||
}
|
||||
|
||||
[JsonProperty("giver")]
|
||||
public KudosuGiver Giver;
|
||||
|
||||
public class KudosuGiver
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url;
|
||||
|
||||
[JsonProperty("username")]
|
||||
public string Username;
|
||||
}
|
||||
|
||||
public KudosuSource Source;
|
||||
|
||||
public KudosuAction Action;
|
||||
|
||||
[JsonProperty("action")]
|
||||
private string action
|
||||
{
|
||||
set
|
||||
{
|
||||
// incoming action may contain a prefix. if it doesn't, it's a legacy forum event.
|
||||
|
||||
string[] split = value.Split('.');
|
||||
|
||||
if (split.Length > 1)
|
||||
Enum.TryParse(split.First().Replace("_", ""), true, out Source);
|
||||
else
|
||||
Source = KudosuSource.Forum;
|
||||
|
||||
Enum.TryParse(split.Last(), true, out Action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum KudosuSource
|
||||
{
|
||||
Unknown,
|
||||
AllowKudosu,
|
||||
Delete,
|
||||
DenyKudosu,
|
||||
Forum,
|
||||
Recalculate,
|
||||
Restore,
|
||||
Vote
|
||||
}
|
||||
|
||||
public enum KudosuAction
|
||||
{
|
||||
Give,
|
||||
Reset,
|
||||
Revoke,
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
|
||||
public Info()
|
||||
{
|
||||
MetadataSection source, tags;
|
||||
MetadataSection source, tags, genre, language;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = 220;
|
||||
Masking = true;
|
||||
@ -83,11 +83,12 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
LayoutDuration = transition_duration,
|
||||
Direction = FillDirection.Full,
|
||||
Children = new[]
|
||||
{
|
||||
source = new MetadataSection("Source"),
|
||||
genre = new MetadataSection("Genre") { Width = 0.5f },
|
||||
language = new MetadataSection("Language") { Width = 0.5f },
|
||||
tags = new MetadataSection("Tags"),
|
||||
},
|
||||
},
|
||||
@ -119,6 +120,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
source.Text = b.NewValue?.Metadata.Source ?? string.Empty;
|
||||
tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty;
|
||||
genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty;
|
||||
language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? string.Empty;
|
||||
};
|
||||
}
|
||||
|
||||
@ -139,7 +142,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
this.FadeOut(transition_duration);
|
||||
Hide();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -149,12 +152,6 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
}
|
||||
}
|
||||
|
||||
public Color4 TextColour
|
||||
{
|
||||
get => textFlow.Colour;
|
||||
set => textFlow.Colour = value;
|
||||
}
|
||||
|
||||
public MetadataSection(string title)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
||||
private Color4 topicColour;
|
||||
private Color4 hoverColour;
|
||||
|
||||
public IEnumerable<string> FilterTerms => new[] { channel.Name };
|
||||
public IEnumerable<string> FilterTerms => new[] { channel.Name, channel.Topic };
|
||||
|
||||
public bool MatchingFilter
|
||||
{
|
||||
@ -121,10 +121,11 @@ namespace osu.Game.Overlays.Chat.Selection
|
||||
{
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Icon = FontAwesome.Solid.User,
|
||||
Size = new Vector2(text_size - 2),
|
||||
Shadow = false,
|
||||
Margin = new MarginPadding { Top = 1 },
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
|
@ -151,6 +151,7 @@ namespace osu.Game.Overlays.Direct
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 20,
|
||||
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
|
||||
Spacing = new Vector2(3),
|
||||
Children = GetDifficultyIcons(colours),
|
||||
},
|
||||
},
|
||||
|
@ -129,6 +129,7 @@ namespace osu.Game.Overlays.Direct
|
||||
AutoSizeAxes = Axes.X,
|
||||
Height = 20,
|
||||
Margin = new MarginPadding { Top = vertical_padding, Bottom = vertical_padding },
|
||||
Spacing = new Vector2(3),
|
||||
Children = GetDifficultyIcons(colours),
|
||||
},
|
||||
},
|
||||
|
@ -28,14 +28,14 @@ namespace osu.Game.Overlays.Direct
|
||||
public readonly BeatmapSetInfo SetInfo;
|
||||
|
||||
private const double hover_transition_time = 400;
|
||||
private const int maximum_difficulty_icons = 15;
|
||||
private const int maximum_difficulty_icons = 10;
|
||||
|
||||
private Container content;
|
||||
|
||||
private BeatmapSetOverlay beatmapSetOverlay;
|
||||
|
||||
public PreviewTrack Preview => PlayButton.Preview;
|
||||
public Bindable<bool> PreviewPlaying => PlayButton.Playing;
|
||||
public Bindable<bool> PreviewPlaying => PlayButton?.Playing;
|
||||
|
||||
protected abstract PlayButton PlayButton { get; }
|
||||
protected abstract Box PreviewBar { get; }
|
||||
@ -190,10 +190,11 @@ namespace osu.Game.Overlays.Direct
|
||||
text = new OsuSpriteText { Font = OsuFont.GetFont(weight: FontWeight.SemiBold, italics: true) },
|
||||
new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Icon = icon,
|
||||
Shadow = true,
|
||||
Size = new Vector2(14),
|
||||
Margin = new MarginPadding { Top = 1 },
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -161,12 +161,12 @@ namespace osu.Game.Overlays.Music
|
||||
{
|
||||
public PlaylistItemHandle()
|
||||
{
|
||||
Anchor = Anchor.TopLeft;
|
||||
Origin = Anchor.TopLeft;
|
||||
Anchor = Anchor.CentreLeft;
|
||||
Origin = Anchor.CentreLeft;
|
||||
Size = new Vector2(12);
|
||||
Icon = FontAwesome.Solid.Bars;
|
||||
Alpha = 0f;
|
||||
Margin = new MarginPadding { Left = 5, Top = 2 };
|
||||
Margin = new MarginPadding { Left = 5 };
|
||||
}
|
||||
|
||||
public override bool HandlePositionalInput => IsPresent;
|
||||
|
@ -296,7 +296,11 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
||||
this.MoveTo(pos, 200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopIn() => this.FadeIn(200, Easing.OutQuint);
|
||||
protected override void PopIn()
|
||||
{
|
||||
instantMove |= !IsPresent;
|
||||
this.FadeIn(200, Easing.OutQuint);
|
||||
}
|
||||
|
||||
protected override void PopOut() => this.FadeOut(200, Easing.OutQuint);
|
||||
}
|
||||
|
@ -0,0 +1,147 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using System;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
||||
{
|
||||
public class DrawableKudosuHistoryItem : CompositeDrawable
|
||||
{
|
||||
private const int height = 25;
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
private readonly APIKudosuHistory historyItem;
|
||||
private readonly LinkFlowContainer linkFlowContainer;
|
||||
private readonly DrawableDate date;
|
||||
|
||||
public DrawableKudosuHistoryItem(APIKudosuHistory historyItem)
|
||||
{
|
||||
this.historyItem = historyItem;
|
||||
|
||||
Height = height;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
linkFlowContainer = new LinkFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(0, 3),
|
||||
},
|
||||
date = new DrawableDate(historyItem.CreatedAt)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
date.Colour = colours.GreySeafoamLighter;
|
||||
var formattedSource = MessageFormatter.FormatText(getString(historyItem));
|
||||
linkFlowContainer.AddLinks(formattedSource.Text, formattedSource.Links);
|
||||
}
|
||||
|
||||
private string getString(APIKudosuHistory item)
|
||||
{
|
||||
string amount = $"{Math.Abs(item.Amount)} kudosu";
|
||||
string post = $"[{item.Post.Title}]({item.Post.Url})";
|
||||
|
||||
switch (item.Source)
|
||||
{
|
||||
case KudosuSource.AllowKudosu:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from kudosu deny repeal of modding post {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.DenyKudosu:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Reset:
|
||||
return $"Denied {amount} from modding post {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Delete:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Reset:
|
||||
return $"Lost {amount} from modding post deletion of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Restore:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from modding post restoration of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Vote:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from obtaining votes in modding post of {post}";
|
||||
|
||||
case KudosuAction.Reset:
|
||||
return $"Lost {amount} from losing votes in modding post of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Recalculate:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from votes recalculation in modding post of {post}";
|
||||
|
||||
case KudosuAction.Reset:
|
||||
return $"Lost {amount} from votes recalculation in modding post of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Forum:
|
||||
|
||||
string giver = $"[{item.Giver?.Username}]({item.Giver?.Url})";
|
||||
|
||||
switch (historyItem.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from {giver} for a post at {post}";
|
||||
|
||||
case KudosuAction.Reset:
|
||||
return $"Kudosu reset by {giver} for the post {post}";
|
||||
|
||||
case KudosuAction.Revoke:
|
||||
return $"Denied kudosu by {giver} for the post {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $"Unknown event ({amount} change)";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.API;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
||||
{
|
||||
public class PaginatedKudosuHistoryContainer : PaginatedContainer<APIKudosuHistory>
|
||||
{
|
||||
public PaginatedKudosuHistoryContainer(Bindable<User> user, string header, string missing)
|
||||
: base(user, header, missing)
|
||||
{
|
||||
ItemsPerPage = 5;
|
||||
}
|
||||
|
||||
protected override APIRequest<List<APIKudosuHistory>> CreateRequest()
|
||||
=> new GetUserKudosuHistoryRequest(User.Value.Id, VisiblePages++, ItemsPerPage);
|
||||
|
||||
protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Overlays.Profile.Sections.Kudosu;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
@ -13,9 +14,10 @@ namespace osu.Game.Overlays.Profile.Sections
|
||||
|
||||
public KudosuSection()
|
||||
{
|
||||
Children = new[]
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new KudosuInfo(User),
|
||||
new PaginatedKudosuHistoryContainer(User, null, @"This user hasn't received any kudosu!"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Judgements
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Child = new SkinnableDrawable($"Play/{Result.Type}", _ => JudgementText = new OsuSpriteText
|
||||
Child = new SkinnableDrawable(new GameplaySkinComponent<HitResult>(Result.Type), _ => JudgementText = new OsuSpriteText
|
||||
{
|
||||
Text = Result.Type.GetDescription().ToUpperInvariant(),
|
||||
Font = OsuFont.Numeric.With(size: 12),
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using JetBrains.Annotations;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
@ -16,9 +18,16 @@ namespace osu.Game.Rulesets.Judgements
|
||||
/// </summary>
|
||||
public HitResult Type;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="HitObject"/> which was judged.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public readonly HitObject HitObject;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Judgement"/> which this <see cref="JudgementResult"/> applies for.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public readonly Judgement Judgement;
|
||||
|
||||
/// <summary>
|
||||
@ -55,9 +64,11 @@ namespace osu.Game.Rulesets.Judgements
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="JudgementResult"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> which was judged.</param>
|
||||
/// <param name="judgement">The <see cref="Judgement"/> to refer to for scoring information.</param>
|
||||
public JudgementResult(Judgement judgement)
|
||||
public JudgementResult([NotNull] HitObject hitObject, [NotNull] Judgement judgement)
|
||||
{
|
||||
HitObject = hitObject;
|
||||
Judgement = judgement;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.TypeExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
@ -278,6 +279,14 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
UpdateResult(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedules an <see cref="Action"/> to this <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only provided temporarily until hitobject pooling is implemented.
|
||||
/// </remarks>
|
||||
protected internal new ScheduledDelegate Schedule(Action action) => base.Schedule(action);
|
||||
|
||||
private double? lifetimeStart;
|
||||
|
||||
public override double LifetimeStart
|
||||
@ -401,7 +410,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
/// Creates the <see cref="JudgementResult"/> that represents the scoring result for this <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
/// <param name="judgement">The <see cref="Judgement"/> that provides the scoring information.</param>
|
||||
protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement);
|
||||
protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(HitObject, judgement);
|
||||
}
|
||||
|
||||
public abstract class DrawableHitObject<TObject> : DrawableHitObject
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -56,6 +57,7 @@ namespace osu.Game.Rulesets.Objects
|
||||
/// <summary>
|
||||
/// The hit windows for this <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public HitWindows HitWindows { get; set; }
|
||||
|
||||
private readonly List<HitObject> nestedHitObjects = new List<HitObject>();
|
||||
@ -111,11 +113,12 @@ namespace osu.Game.Rulesets.Objects
|
||||
|
||||
/// <summary>
|
||||
/// Creates the <see cref="HitWindows"/> for this <see cref="HitObject"/>.
|
||||
/// This can be null to indicate that the <see cref="HitObject"/> has no <see cref="HitWindows"/>.
|
||||
/// This can be null to indicate that the <see cref="HitObject"/> has no <see cref="HitWindows"/> and timing errors should not be displayed to the user.
|
||||
/// <para>
|
||||
/// This will only be invoked if <see cref="HitWindows"/> hasn't been set externally (e.g. from a <see cref="BeatmapConverter{T}"/>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <summary>
|
||||
/// Whether all <see cref="Judgement"/>s have been processed.
|
||||
/// </summary>
|
||||
protected virtual bool HasCompleted => false;
|
||||
public virtual bool HasCompleted => false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this ScoreProcessor has already triggered the failed state.
|
||||
@ -205,7 +205,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
private const double combo_portion = 0.7;
|
||||
private const double max_score = 1000000;
|
||||
|
||||
protected sealed override bool HasCompleted => JudgedHits == MaxHits;
|
||||
public sealed override bool HasCompleted => JudgedHits == MaxHits;
|
||||
|
||||
protected int MaxHits { get; private set; }
|
||||
protected int JudgedHits { get; private set; }
|
||||
@ -275,7 +275,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
if (judgement == null)
|
||||
return;
|
||||
|
||||
var result = CreateResult(judgement);
|
||||
var result = CreateResult(obj, judgement);
|
||||
if (result == null)
|
||||
throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");
|
||||
|
||||
@ -441,8 +441,9 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <summary>
|
||||
/// Creates the <see cref="JudgementResult"/> that represents the scoring result for a <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> which was judged.</param>
|
||||
/// <param name="judgement">The <see cref="Judgement"/> that provides the scoring information.</param>
|
||||
protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement);
|
||||
protected virtual JudgementResult CreateResult(HitObject hitObject, Judgement judgement) => new JudgementResult(hitObject, judgement);
|
||||
}
|
||||
|
||||
public enum ScoringMode
|
||||
|
@ -13,6 +13,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Input;
|
||||
@ -215,10 +216,6 @@ namespace osu.Game.Rulesets.UI
|
||||
continueResume();
|
||||
}
|
||||
|
||||
public ResumeOverlay ResumeOverlay { get; private set; }
|
||||
|
||||
protected virtual ResumeOverlay CreateResumeOverlay() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Creates and adds the visual representation of a <see cref="TObject"/> to this <see cref="DrawableRuleset{TObject}"/>.
|
||||
/// </summary>
|
||||
@ -389,6 +386,35 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public abstract GameplayCursorContainer Cursor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional overlay used when resuming gameplay from a paused state.
|
||||
/// </summary>
|
||||
public ResumeOverlay ResumeOverlay { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns first available <see cref="HitWindows"/> provided by a <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
public HitWindows FirstAvailableHitWindows
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var h in Objects)
|
||||
{
|
||||
if (h.HitWindows != null)
|
||||
return h.HitWindows;
|
||||
|
||||
foreach (var n in h.NestedHitObjects)
|
||||
if (n.HitWindows != null)
|
||||
return n.HitWindows;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ResumeOverlay CreateResumeOverlay() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Sets a replay to be used, overriding local input.
|
||||
/// </summary>
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
@ -50,8 +51,13 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
public override bool Remove(DrawableHitObject hitObject)
|
||||
{
|
||||
var result = base.Remove(hitObject);
|
||||
|
||||
if (result)
|
||||
{
|
||||
initialStateCache.Invalidate();
|
||||
hitObjectInitialStateCache.Remove(hitObject);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -86,13 +92,34 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
scrollingInfo.Algorithm.Reset();
|
||||
|
||||
foreach (var obj in Objects)
|
||||
{
|
||||
computeLifetimeStartRecursive(obj);
|
||||
computeInitialStateRecursive(obj);
|
||||
}
|
||||
|
||||
initialStateCache.Validate();
|
||||
}
|
||||
}
|
||||
|
||||
private void computeInitialStateRecursive(DrawableHitObject hitObject)
|
||||
private void computeLifetimeStartRecursive(DrawableHitObject hitObject)
|
||||
{
|
||||
hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value);
|
||||
|
||||
foreach (var obj in hitObject.NestedHitObjects)
|
||||
computeLifetimeStartRecursive(obj);
|
||||
}
|
||||
|
||||
private readonly Dictionary<DrawableHitObject, Cached> hitObjectInitialStateCache = new Dictionary<DrawableHitObject, Cached>();
|
||||
|
||||
// Cant use AddOnce() since the delegate is re-constructed every invocation
|
||||
private void computeInitialStateRecursive(DrawableHitObject hitObject) => hitObject.Schedule(() =>
|
||||
{
|
||||
if (!hitObjectInitialStateCache.TryGetValue(hitObject, out var cached))
|
||||
cached = hitObjectInitialStateCache[hitObject] = new Cached();
|
||||
|
||||
if (cached.IsValid)
|
||||
return;
|
||||
|
||||
double endTime = hitObject.HitObject.StartTime;
|
||||
|
||||
if (hitObject.HitObject is IHasEndTime e)
|
||||
@ -113,7 +140,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
}
|
||||
}
|
||||
|
||||
hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value);
|
||||
hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime, timeRange.Value, scrollLength);
|
||||
|
||||
foreach (var obj in hitObject.NestedHitObjects)
|
||||
@ -123,7 +149,9 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
// Nested hitobjects don't need to scroll, but they do need accurate positions
|
||||
updatePosition(obj, hitObject.HitObject.StartTime);
|
||||
}
|
||||
}
|
||||
|
||||
cached.Validate();
|
||||
});
|
||||
|
||||
protected override void UpdateAfterChildrenLife()
|
||||
{
|
||||
|
@ -4,6 +4,9 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Edit
|
||||
{
|
||||
@ -35,5 +38,41 @@ namespace osu.Game.Screens.Edit
|
||||
protected override int DefaultMinValue => VALID_DIVISORS.First();
|
||||
protected override int DefaultMaxValue => VALID_DIVISORS.Last();
|
||||
protected override int DefaultPrecision => 1;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the appropriate colour for a beat divisor.
|
||||
/// </summary>
|
||||
/// <param name="beatDivisor">The beat divisor.</param>
|
||||
/// <param name="colours">The set of colours.</param>
|
||||
/// <returns>The applicable colour from <paramref name="colours"/> for <paramref name="beatDivisor"/>.</returns>
|
||||
public static ColourInfo GetColourFor(int beatDivisor, OsuColour colours)
|
||||
{
|
||||
switch (beatDivisor)
|
||||
{
|
||||
case 2:
|
||||
return colours.BlueLight;
|
||||
|
||||
case 4:
|
||||
return colours.Blue;
|
||||
|
||||
case 8:
|
||||
return colours.BlueDarker;
|
||||
|
||||
case 16:
|
||||
return colours.PurpleDark;
|
||||
|
||||
case 3:
|
||||
return colours.YellowLight;
|
||||
|
||||
case 6:
|
||||
return colours.Yellow;
|
||||
|
||||
case 12:
|
||||
return colours.YellowDarker;
|
||||
|
||||
default:
|
||||
return Color4.White;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
private Marker marker;
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
private readonly BindableBeatDivisor beatDivisor;
|
||||
private readonly int[] availableDivisors;
|
||||
|
||||
@ -204,11 +207,12 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
foreach (var t in availableDivisors)
|
||||
{
|
||||
AddInternal(new Tick(t)
|
||||
AddInternal(new Tick
|
||||
{
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativePositionAxes = Axes.X,
|
||||
Colour = BindableBeatDivisor.GetColourFor(t, colours),
|
||||
X = getMappedPosition(t)
|
||||
});
|
||||
}
|
||||
@ -284,11 +288,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
private class Tick : CompositeDrawable
|
||||
{
|
||||
private readonly int divisor;
|
||||
|
||||
public Tick(int divisor)
|
||||
public Tick()
|
||||
{
|
||||
this.divisor = divisor;
|
||||
Size = new Vector2(2.5f, 10);
|
||||
|
||||
InternalChild = new Box { RelativeSizeAxes = Axes.Both };
|
||||
@ -296,42 +297,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
CornerRadius = 0.5f;
|
||||
Masking = true;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
Colour = getColourForDivisor(divisor, colours);
|
||||
}
|
||||
|
||||
private ColourInfo getColourForDivisor(int divisor, OsuColour colours)
|
||||
{
|
||||
switch (divisor)
|
||||
{
|
||||
case 2:
|
||||
return colours.BlueLight;
|
||||
|
||||
case 4:
|
||||
return colours.Blue;
|
||||
|
||||
case 8:
|
||||
return colours.BlueDarker;
|
||||
|
||||
case 16:
|
||||
return colours.PurpleDark;
|
||||
|
||||
case 3:
|
||||
return colours.YellowLight;
|
||||
|
||||
case 6:
|
||||
return colours.Yellow;
|
||||
|
||||
case 12:
|
||||
return colours.YellowDarker;
|
||||
|
||||
default:
|
||||
return Color4.White;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Marker : CompositeDrawable
|
||||
|
@ -77,7 +77,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
Scheduler.AddDelayed(delegate
|
||||
{
|
||||
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu.
|
||||
// Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu.
|
||||
if (menuMusic.Value)
|
||||
{
|
||||
track.Restart();
|
||||
|
@ -47,7 +47,7 @@ namespace osu.Game.Screens.Menu
|
||||
private const float visualiser_rounds = 5;
|
||||
|
||||
/// <summary>
|
||||
/// How much should each bar go down each milisecond (based on a full bar).
|
||||
/// How much should each bar go down each millisecond (based on a full bar).
|
||||
/// </summary>
|
||||
private const float decay_per_milisecond = 0.0024f;
|
||||
|
||||
@ -161,7 +161,7 @@ namespace osu.Game.Screens.Menu
|
||||
private IShader shader;
|
||||
private Texture texture;
|
||||
|
||||
//Asuming the logo is a circle, we don't need a second dimension.
|
||||
//Assuming the logo is a circle, we don't need a second dimension.
|
||||
private float size;
|
||||
|
||||
private Color4 colour;
|
||||
|
@ -229,7 +229,7 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a new extenral animation. Handled queueing and finishing previous animations in a sane way.
|
||||
/// Schedule a new external animation. Handled queueing and finishing previous animations in a sane way.
|
||||
/// </summary>
|
||||
/// <param name="action">The animation to be performed</param>
|
||||
/// <param name="waitForPrevious">If true, the new animation is delayed until all previous transforms finish. If false, existing transformed are cleared.</param>
|
||||
|
@ -49,6 +49,9 @@ namespace osu.Game.Screens.Play.HUD
|
||||
|
||||
private void onNewJudgement(JudgementResult result)
|
||||
{
|
||||
if (result.HitObject.HitWindows == null)
|
||||
return;
|
||||
|
||||
foreach (var c in Children)
|
||||
c.OnNewJudgement(result);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -259,7 +258,7 @@ namespace osu.Game.Screens.Play
|
||||
Margin = new MarginPadding { Top = 20, Right = 10 },
|
||||
};
|
||||
|
||||
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.Objects.FirstOrDefault()?.HitWindows);
|
||||
protected virtual HitErrorDisplay CreateHitErrorDisplayOverlay() => new HitErrorDisplay(scoreProcessor, drawableRuleset.FirstAvailableHitWindows);
|
||||
|
||||
protected virtual PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay();
|
||||
|
||||
|
@ -178,6 +178,7 @@ namespace osu.Game.Screens.Play
|
||||
},
|
||||
// display the cursor above some HUD elements.
|
||||
DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
|
||||
DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(),
|
||||
HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value)
|
||||
{
|
||||
HoldToQuit =
|
||||
|
@ -414,7 +414,11 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
Logger.Log($"beatmap changed from \"{Beatmap.Value.BeatmapInfo}\" to \"{beatmap}\"");
|
||||
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
||||
WorkingBeatmap previous = Beatmap.Value;
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, previous);
|
||||
|
||||
if (this.IsCurrentScreen() && Beatmap.Value?.Track != previous?.Track)
|
||||
ensurePlayingSelected();
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
@ -425,8 +429,6 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
|
||||
if (this.IsCurrentScreen())
|
||||
ensurePlayingSelected();
|
||||
UpdateBeatmap(Beatmap.Value);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Skinning
|
||||
private readonly Bindable<bool> beatmapHitsounds = new Bindable<bool>();
|
||||
|
||||
protected override bool AllowConfigurationLookup => beatmapSkins.Value;
|
||||
protected override bool AllowDrawableLookup(string componentName) => beatmapSkins.Value;
|
||||
protected override bool AllowDrawableLookup(ISkinComponent component) => beatmapSkins.Value;
|
||||
protected override bool AllowTextureLookup(string componentName) => beatmapSkins.Value;
|
||||
protected override bool AllowSampleLookup(ISampleInfo componentName) => beatmapHitsounds.Value;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
|
||||
using osu.Framework.Audio.Sample;
|
||||
@ -16,7 +16,7 @@ namespace osu.Game.Skinning
|
||||
Configuration = new DefaultSkinConfiguration();
|
||||
}
|
||||
|
||||
public override Drawable GetDrawableComponent(string componentName) => null;
|
||||
public override Drawable GetDrawableComponent(ISkinComponent component) => null;
|
||||
|
||||
public override Texture GetTexture(string componentName) => null;
|
||||
|
||||
|
23
osu.Game/Skinning/GameplaySkinComponent.cs
Normal file
23
osu.Game/Skinning/GameplaySkinComponent.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public class GameplaySkinComponent<T> : ISkinComponent where T : struct
|
||||
{
|
||||
public readonly T Component;
|
||||
|
||||
public GameplaySkinComponent(T component)
|
||||
{
|
||||
Component = component;
|
||||
}
|
||||
|
||||
protected virtual string RulesetPrefix => string.Empty;
|
||||
protected virtual string ComponentName => Component.ToString();
|
||||
|
||||
public string LookupName =>
|
||||
string.Join("/", new[] { "Gameplay", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s)));
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ namespace osu.Game.Skinning
|
||||
/// </summary>
|
||||
public interface ISkin
|
||||
{
|
||||
Drawable GetDrawableComponent(string componentName);
|
||||
Drawable GetDrawableComponent(ISkinComponent component);
|
||||
|
||||
Texture GetTexture(string componentName);
|
||||
|
||||
|
10
osu.Game/Skinning/ISkinComponent.cs
Normal file
10
osu.Game/Skinning/ISkinComponent.cs
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
public interface ISkinComponent
|
||||
{
|
||||
string LookupName { get; }
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user