Merge branch 'master' into taiko-drumroll-party

# Conflicts:
#	osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs
#	osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
This commit is contained in:
Tim Oliver
2020-04-22 23:15:48 +08:00
245 changed files with 6349 additions and 1990 deletions

View File

@ -1,9 +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 osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -14,13 +13,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
public DrawableCentreHit(Hit hit)
: base(hit)
{
MainPiece.Add(new CentreHitSymbolPiece());
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
MainPiece.AccentColour = colours.PinkDarker;
}
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit),
_ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
}
}

View File

@ -14,6 +14,8 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -29,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
/// </summary>
private int rollingHits;
private readonly Container<DrawableDrumRollTick> tickContainer;
private Container tickContainer;
private Color4 colourIdle;
private Color4 colourEngaged;
@ -46,14 +48,20 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
: base(drumRoll)
{
RelativeSizeAxes = Axes.Y;
MainPiece.Add(tickContainer = new Container<DrawableDrumRollTick> { RelativeSizeAxes = Axes.Both });
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
MainPiece.AccentColour = colourIdle = colours.YellowDark;
colourIdle = colours.YellowDark;
colourEngaged = colours.YellowDarker;
updateColour();
Content.Add(tickContainer = new Container { RelativeSizeAxes = Axes.Both });
if (MainPiece.Drawable is IHasAccentColour accentMain)
accentMain.AccentColour = colourIdle;
}
protected override void LoadComplete()
@ -92,7 +100,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
return base.CreateNestedHitObject(hitObject);
}
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollBody),
_ => new ElongatedCirclePiece());
public override bool OnPressed(TaikoAction action)
{
@ -120,8 +129,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
rollingHits = Math.Clamp(rollingHits, 0, rolling_hits_for_engaged_colour);
Color4 newColour = Interpolation.ValueAt((float)rollingHits / rolling_hits_for_engaged_colour, colourIdle, colourEngaged, 0, 1);
MainPiece.FadeAccent(newColour, 100);
updateColour();
}
protected override void CheckForResult(bool userTriggered, double timeOffset)
@ -153,8 +161,22 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
protected override void Update()
{
base.Update();
OriginPosition = new Vector2(DrawHeight);
Content.X = DrawHeight / 2;
}
protected override DrawableStrongNestedHit CreateStrongHit(StrongHitObject hitObject) => new StrongNestedHit(hitObject, this);
private void updateColour()
{
Color4 newColour = Interpolation.ValueAt((float)rollingHits / rolling_hits_for_engaged_colour, colourIdle, colourEngaged, 0, 1);
(MainPiece.Drawable as IHasAccentColour)?.FadeAccent(newColour, 100);
}
private class StrongNestedHit : DrawableStrongNestedHit
{
public StrongNestedHit(StrongHitObject strong, DrawableDrumRoll drumRoll)

View File

@ -6,6 +6,7 @@ using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -25,10 +26,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
public override bool DisplayResult => false;
protected override TaikoPiece CreateMainPiece() => new TickPiece
{
Filled = HitObject.FirstTick
};
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick),
_ => new TickPiece
{
Filled = HitObject.FirstTick
});
protected override void CheckForResult(bool userTriggered, double timeOffset)
{

View File

@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
// If we're far enough away from the left stage, we should bring outselves in front of it
ProxyContent();
var flash = (MainPiece as CirclePiece)?.FlashBox;
var flash = (MainPiece.Drawable as CirclePiece)?.FlashBox;
flash?.FadeTo(0.9f).FadeOut(300);
const float gravity_time = 300;

View File

@ -7,6 +7,7 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -17,13 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
public DrawableRimHit(Hit hit)
: base(hit)
{
MainPiece.Add(new RimHitSymbolPiece());
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
MainPiece.AccentColour = colours.BlueDarker;
}
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit),
_ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
}
}

View File

@ -9,11 +9,12 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osuTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -34,8 +35,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
private readonly CircularContainer targetRing;
private readonly CircularContainer expandingRing;
private readonly SwellSymbolPiece symbol;
public DrawableSwell(Swell swell)
: base(swell)
{
@ -107,18 +106,23 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
});
AddInternal(ticks = new Container<DrawableSwellTick> { RelativeSizeAxes = Axes.Both });
MainPiece.Add(symbol = new SwellSymbolPiece());
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
MainPiece.AccentColour = colours.YellowDark;
expandingRing.Colour = colours.YellowLight;
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
}
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Swell),
_ => new SwellCirclePiece
{
// to allow for rotation transform
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});
protected override void LoadComplete()
{
base.LoadComplete();
@ -182,7 +186,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
.Then()
.FadeTo(completion / 8, 2000, Easing.OutQuint);
symbol.RotateTo((float)(completion * HitObject.Duration / 8), 4000, Easing.OutQuint);
MainPiece.Drawable.RotateTo((float)(completion * HitObject.Duration / 8), 4000, Easing.OutQuint);
expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, Easing.OutQuint);

View File

@ -3,6 +3,8 @@
using osu.Framework.Graphics;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -28,5 +30,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
public override bool OnPressed(TaikoAction action) => false;
protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick),
_ => new TickPiece());
}
}

View File

@ -4,7 +4,6 @@
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using osuTK;
using System.Linq;
using osu.Game.Audio;
@ -12,6 +11,7 @@ using System.Collections.Generic;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Objects;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
/// <summary>
/// Moves <see cref="Content"/> to a layer proxied above the playfield.
/// Does nothing is content is already proxied.
/// Does nothing if content is already proxied.
/// </summary>
protected void ProxyContent()
{
@ -110,19 +110,19 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
public abstract class DrawableTaikoHitObject<TTaikoHit> : DrawableTaikoHitObject
where TTaikoHit : TaikoHitObject
public abstract class DrawableTaikoHitObject<TObject> : DrawableTaikoHitObject
where TObject : TaikoHitObject
{
public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
public new TTaikoHit HitObject;
public new TObject HitObject;
protected readonly Vector2 BaseSize;
protected readonly TaikoPiece MainPiece;
protected readonly SkinnableDrawable MainPiece;
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
protected DrawableTaikoHitObject(TTaikoHit hitObject)
protected DrawableTaikoHitObject(TObject hitObject)
: base(hitObject)
{
HitObject = hitObject;
@ -134,7 +134,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
Content.Add(MainPiece = CreateMainPiece());
MainPiece.KiaiMode = HitObject.Kiai;
AddInternal(strongHitContainer = new Container<DrawableStrongNestedHit>());
}
@ -171,7 +170,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
// Normal and clap samples are handled by the drum
protected override IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
protected abstract SkinnableDrawable CreateMainPiece();
/// <summary>
/// Creates the handler for this <see cref="DrawableHitObject"/>'s <see cref="StrongHitObject"/>.

View File

@ -0,0 +1,52 @@
// 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 osuTK;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class CentreHitCirclePiece : CirclePiece
{
public CentreHitCirclePiece()
{
Add(new CentreHitSymbolPiece());
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.PinkDarker;
}
/// <summary>
/// The symbol used for centre hit pieces.
/// </summary>
public class CentreHitSymbolPiece : Container
{
public CentreHitSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(SYMBOL_SIZE);
Padding = new MarginPadding(SYMBOL_BORDER);
Children = new[]
{
new CircularContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
Children = new[] { new Box { RelativeSizeAxes = Axes.Both } }
}
};
}
}
}
}

View File

@ -1,36 +0,0 @@
// 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.Framework.Graphics.Containers;
using osuTK;
using osu.Framework.Graphics.Shapes;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
/// <summary>
/// The symbol used for centre hit pieces.
/// </summary>
public class CentreHitSymbolPiece : Container
{
public CentreHitSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(CirclePiece.SYMBOL_SIZE);
Padding = new MarginPadding(CirclePiece.SYMBOL_BORDER);
Children = new[]
{
new CircularContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
Children = new[] { new Box { RelativeSizeAxes = Axes.Both } }
}
};
}
}
}

View File

@ -10,6 +10,8 @@ using osuTK.Graphics;
using osu.Game.Beatmaps.ControlPoints;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Effects;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
@ -20,21 +22,23 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
/// for a usage example.
/// </para>
/// </summary>
public class CirclePiece : TaikoPiece
public abstract class CirclePiece : BeatSyncedContainer, IHasAccentColour
{
public const float SYMBOL_SIZE = 0.45f;
public const float SYMBOL_BORDER = 8;
private const double pre_beat_transition_time = 80;
private Color4 accentColour;
/// <summary>
/// The colour of the inner circle and outer glows.
/// </summary>
public override Color4 AccentColour
public Color4 AccentColour
{
get => base.AccentColour;
get => accentColour;
set
{
base.AccentColour = value;
accentColour = value;
background.Colour = AccentColour;
@ -42,15 +46,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
}
}
private bool kiaiMode;
/// <summary>
/// Whether Kiai mode effects are enabled for this circle piece.
/// </summary>
public override bool KiaiMode
public bool KiaiMode
{
get => base.KiaiMode;
get => kiaiMode;
set
{
base.KiaiMode = value;
kiaiMode = value;
resetEdgeEffects();
}
@ -64,8 +70,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
public Box FlashBox;
public CirclePiece()
protected CirclePiece()
{
RelativeSizeAxes = Axes.Both;
EarlyActivationMilliseconds = pre_beat_transition_time;
AddRangeInternal(new Drawable[]

View File

@ -1,7 +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.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
@ -12,18 +14,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
RelativeSizeAxes = Axes.Y;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.YellowDark;
}
protected override void Update()
{
base.Update();
var padding = Content.DrawHeight * Content.Width / 2;
Content.Padding = new MarginPadding
{
Left = padding,
Right = padding,
};
Width = Parent.DrawSize.X + DrawHeight;
}
}

View File

@ -0,0 +1,55 @@
// 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.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class RimHitCirclePiece : CirclePiece
{
public RimHitCirclePiece()
{
Add(new RimHitSymbolPiece());
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.BlueDarker;
}
/// <summary>
/// The symbol used for rim hit pieces.
/// </summary>
public class RimHitSymbolPiece : CircularContainer
{
public RimHitSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(SYMBOL_SIZE);
BorderThickness = SYMBOL_BORDER;
BorderColour = Color4.White;
Masking = true;
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
};
}
}
}
}

View File

@ -1,39 +0,0 @@
// 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.Framework.Graphics.Containers;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics.Shapes;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
/// <summary>
/// The symbol used for rim hit pieces.
/// </summary>
public class RimHitSymbolPiece : CircularContainer
{
public RimHitSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(CirclePiece.SYMBOL_SIZE);
BorderThickness = CirclePiece.SYMBOL_BORDER;
BorderColour = Color4.White;
Masking = true;
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
};
}
}
}

View File

@ -1,36 +1,52 @@
// 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 osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
/// <summary>
/// The symbol used for swell pieces.
/// </summary>
public class SwellSymbolPiece : Container
public class SwellCirclePiece : CirclePiece
{
public SwellSymbolPiece()
public SwellCirclePiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Add(new SwellSymbolPiece());
}
RelativeSizeAxes = Axes.Both;
Size = new Vector2(CirclePiece.SYMBOL_SIZE);
Padding = new MarginPadding(CirclePiece.SYMBOL_BORDER);
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.YellowDark;
}
Children = new[]
/// <summary>
/// The symbol used for swell pieces.
/// </summary>
public class SwellSymbolPiece : Container
{
public SwellSymbolPiece()
{
new SpriteIcon
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(SYMBOL_SIZE);
Padding = new MarginPadding(SYMBOL_BORDER);
Children = new[]
{
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.Solid.Asterisk,
Shadow = false
}
};
new SpriteIcon
{
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.Solid.Asterisk,
Shadow = false
}
};
}
}
}
}

View File

@ -1,28 +0,0 @@
// 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.Graphics;
using osuTK.Graphics;
using osu.Game.Graphics.Containers;
using osu.Framework.Graphics;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class TaikoPiece : BeatSyncedContainer, IHasAccentColour
{
/// <summary>
/// The colour of the inner circle and outer glows.
/// </summary>
public virtual Color4 AccentColour { get; set; }
/// <summary>
/// Whether Kiai mode effects are enabled for this circle piece.
/// </summary>
public virtual bool KiaiMode { get; set; }
public TaikoPiece()
{
RelativeSizeAxes = Axes.Both;
}
}
}

View File

@ -9,7 +9,7 @@ using osu.Framework.Graphics.Shapes;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class TickPiece : TaikoPiece
public class TickPiece : CompositeDrawable
{
/// <summary>
/// Any tick that is not the first for a drumroll is not filled, but is instead displayed
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
FillMode = FillMode.Fit;
Size = new Vector2(tick_size);
Add(new CircularContainer
InternalChild = new CircularContainer
{
RelativeSizeAxes = Axes.Both,
Masking = true,
@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
AlwaysPresent = true
}
}
});
};
}
}
}