2019-01-24 16:43:03 +08:00
// 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.
2018-04-13 17:19:50 +08:00
2018-11-20 15:51:59 +08:00
using osuTK ;
2018-04-13 17:19:50 +08:00
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
using osu.Game.Rulesets.Objects.Drawables ;
using osu.Game.Rulesets.Osu.Objects ;
using osu.Game.Rulesets.Osu.Objects.Drawables ;
using osu.Game.Rulesets.Osu.Objects.Drawables.Connections ;
using osu.Game.Rulesets.UI ;
using System.Linq ;
using osu.Game.Rulesets.Judgements ;
2019-03-06 11:34:58 +08:00
using osu.Game.Rulesets.Osu.UI.Cursor ;
2019-07-17 18:25:41 +08:00
using osu.Game.Skinning ;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Rulesets.Osu.UI
{
public class OsuPlayfield : Playfield
{
2018-12-13 13:55:28 +08:00
private readonly ApproachCircleProxyContainer approachCircles ;
2018-04-13 17:19:50 +08:00
private readonly JudgementContainer < DrawableOsuJudgement > judgementLayer ;
private readonly ConnectionRenderer < OsuHitObject > connectionLayer ;
public static readonly Vector2 BASE_SIZE = new Vector2 ( 512 , 384 ) ;
2019-03-29 10:38:45 +08:00
protected override GameplayCursorContainer CreateCursor ( ) = > new OsuCursorContainer ( ) ;
2019-03-08 13:59:45 +08:00
2018-04-13 17:19:50 +08:00
public OsuPlayfield ( )
{
2019-03-26 12:31:49 +08:00
InternalChildren = new Drawable [ ]
2018-04-13 17:19:50 +08:00
{
2019-03-26 12:31:49 +08:00
connectionLayer = new FollowPointRenderer
{
RelativeSizeAxes = Axes . Both ,
Depth = 2 ,
} ,
judgementLayer = new JudgementContainer < DrawableOsuJudgement >
{
RelativeSizeAxes = Axes . Both ,
Depth = 1 ,
} ,
2019-07-17 18:25:41 +08:00
// Todo: This should not exist, but currently helps to reduce LOH allocations due to unbinding skin source events on judgement disposal
// Todo: Remove when hitobjects are properly pooled
2019-08-26 11:21:49 +08:00
new SkinProvidingContainer ( null )
2019-07-17 18:25:41 +08:00
{
Child = HitObjectContainer ,
} ,
2019-03-26 12:31:49 +08:00
approachCircles = new ApproachCircleProxyContainer
2018-04-13 17:19:50 +08:00
{
2019-03-26 12:31:49 +08:00
RelativeSizeAxes = Axes . Both ,
Depth = - 1 ,
} ,
2018-09-21 13:02:32 +08:00
} ;
2018-04-13 17:19:50 +08:00
}
public override void Add ( DrawableHitObject h )
{
2018-08-06 09:54:16 +08:00
h . OnNewResult + = onNewResult ;
2018-04-13 17:19:50 +08:00
2019-02-28 13:35:00 +08:00
if ( h is IDrawableHitObjectWithProxiedApproach c )
2018-12-13 13:55:28 +08:00
{
var original = c . ProxiedLayer ;
2019-02-27 14:43:20 +08:00
2019-02-27 15:35:11 +08:00
// Hitobjects only have lifetimes set on LoadComplete. For nested hitobjects (e.g. SliderHeads), this only happens when the parenting slider becomes visible.
// This delegation is required to make sure that the approach circles for those not-yet-loaded objects aren't added prematurely.
2018-12-13 13:55:28 +08:00
original . OnLoadComplete + = addApproachCircleProxy ;
}
2018-04-13 17:19:50 +08:00
base . Add ( h ) ;
}
2018-12-13 13:55:28 +08:00
private void addApproachCircleProxy ( Drawable d )
{
var proxy = d . CreateProxy ( ) ;
proxy . LifetimeStart = d . LifetimeStart ;
proxy . LifetimeEnd = d . LifetimeEnd ;
approachCircles . Add ( proxy ) ;
}
2018-04-13 17:19:50 +08:00
public override void PostProcess ( )
{
2018-08-30 12:30:23 +08:00
connectionLayer . HitObjects = HitObjectContainer . Objects . Select ( d = > d . HitObject ) . OfType < OsuHitObject > ( ) ;
2018-04-13 17:19:50 +08:00
}
2018-08-06 09:54:16 +08:00
private void onNewResult ( DrawableHitObject judgedObject , JudgementResult result )
2018-04-13 17:19:50 +08:00
{
2019-02-21 17:56:34 +08:00
if ( ! judgedObject . DisplayResult | | ! DisplayJudgements . Value )
2018-04-13 17:19:50 +08:00
return ;
2018-08-02 19:36:38 +08:00
DrawableOsuJudgement explosion = new DrawableOsuJudgement ( result , judgedObject )
2018-04-13 17:19:50 +08:00
{
Origin = Anchor . Centre ,
2018-09-23 10:54:38 +08:00
Position = ( ( OsuHitObject ) judgedObject . HitObject ) . StackedEndPosition ,
2018-09-25 09:18:55 +08:00
Scale = new Vector2 ( ( ( OsuHitObject ) judgedObject . HitObject ) . Scale * 1.65f )
2018-04-13 17:19:50 +08:00
} ;
judgementLayer . Add ( explosion ) ;
}
2018-11-13 11:52:04 +08:00
public override bool ReceivePositionalInputAt ( Vector2 screenSpacePos ) = > HitObjectContainer . ReceivePositionalInputAt ( screenSpacePos ) ;
2018-12-13 13:55:28 +08:00
private class ApproachCircleProxyContainer : LifetimeManagementContainer
{
public void Add ( Drawable approachCircleProxy ) = > AddInternal ( approachCircleProxy ) ;
}
2018-04-13 17:19:50 +08:00
}
}