2019-01-24 08:43:03 +00: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 09:19:50 +00:00
2018-11-20 07:51:59 +00:00
using osuTK ;
2018-04-13 09:19:50 +00: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 03:34:58 +00:00
using osu.Game.Rulesets.Osu.UI.Cursor ;
2019-07-17 10:25:41 +00:00
using osu.Game.Skinning ;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Rulesets.Osu.UI
{
public class OsuPlayfield : Playfield
{
2018-12-13 05:55:28 +00:00
private readonly ApproachCircleProxyContainer approachCircles ;
2018-04-13 09:19:50 +00:00
private readonly JudgementContainer < DrawableOsuJudgement > judgementLayer ;
private readonly ConnectionRenderer < OsuHitObject > connectionLayer ;
public static readonly Vector2 BASE_SIZE = new Vector2 ( 512 , 384 ) ;
2019-03-29 02:38:45 +00:00
protected override GameplayCursorContainer CreateCursor ( ) = > new OsuCursorContainer ( ) ;
2019-03-08 05:59:45 +00:00
2018-04-13 09:19:50 +00:00
public OsuPlayfield ( )
{
2019-03-26 04:31:49 +00:00
InternalChildren = new Drawable [ ]
2018-04-13 09:19:50 +00:00
{
2019-03-26 04:31:49 +00:00
connectionLayer = new FollowPointRenderer
{
RelativeSizeAxes = Axes . Both ,
Depth = 2 ,
} ,
judgementLayer = new JudgementContainer < DrawableOsuJudgement >
{
RelativeSizeAxes = Axes . Both ,
Depth = 1 ,
} ,
2019-07-17 10:25:41 +00: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 03:21:49 +00:00
new SkinProvidingContainer ( null )
2019-07-17 10:25:41 +00:00
{
Child = HitObjectContainer ,
} ,
2019-03-26 04:31:49 +00:00
approachCircles = new ApproachCircleProxyContainer
2018-04-13 09:19:50 +00:00
{
2019-03-26 04:31:49 +00:00
RelativeSizeAxes = Axes . Both ,
Depth = - 1 ,
} ,
2018-09-21 05:02:32 +00:00
} ;
2018-04-13 09:19:50 +00:00
}
public override void Add ( DrawableHitObject h )
{
2018-08-06 01:54:16 +00:00
h . OnNewResult + = onNewResult ;
2018-04-13 09:19:50 +00:00
2019-02-28 05:35:00 +00:00
if ( h is IDrawableHitObjectWithProxiedApproach c )
2018-12-13 05:55:28 +00:00
{
var original = c . ProxiedLayer ;
2019-02-27 06:43:20 +00:00
2019-02-27 07:35:11 +00: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 05:55:28 +00:00
original . OnLoadComplete + = addApproachCircleProxy ;
}
2018-04-13 09:19:50 +00:00
base . Add ( h ) ;
}
2018-12-13 05:55:28 +00:00
private void addApproachCircleProxy ( Drawable d )
{
var proxy = d . CreateProxy ( ) ;
proxy . LifetimeStart = d . LifetimeStart ;
proxy . LifetimeEnd = d . LifetimeEnd ;
approachCircles . Add ( proxy ) ;
}
2018-04-13 09:19:50 +00:00
public override void PostProcess ( )
{
2018-08-30 04:30:23 +00:00
connectionLayer . HitObjects = HitObjectContainer . Objects . Select ( d = > d . HitObject ) . OfType < OsuHitObject > ( ) ;
2018-04-13 09:19:50 +00:00
}
2018-08-06 01:54:16 +00:00
private void onNewResult ( DrawableHitObject judgedObject , JudgementResult result )
2018-04-13 09:19:50 +00:00
{
2019-02-21 09:56:34 +00:00
if ( ! judgedObject . DisplayResult | | ! DisplayJudgements . Value )
2018-04-13 09:19:50 +00:00
return ;
2018-08-02 11:36:38 +00:00
DrawableOsuJudgement explosion = new DrawableOsuJudgement ( result , judgedObject )
2018-04-13 09:19:50 +00:00
{
Origin = Anchor . Centre ,
2018-09-23 02:54:38 +00:00
Position = ( ( OsuHitObject ) judgedObject . HitObject ) . StackedEndPosition ,
2018-09-25 01:18:55 +00:00
Scale = new Vector2 ( ( ( OsuHitObject ) judgedObject . HitObject ) . Scale * 1.65f )
2018-04-13 09:19:50 +00:00
} ;
judgementLayer . Add ( explosion ) ;
}
2018-11-13 03:52:04 +00:00
public override bool ReceivePositionalInputAt ( Vector2 screenSpacePos ) = > HitObjectContainer . ReceivePositionalInputAt ( screenSpacePos ) ;
2018-12-13 05:55:28 +00:00
private class ApproachCircleProxyContainer : LifetimeManagementContainer
{
public void Add ( Drawable approachCircleProxy ) = > AddInternal ( approachCircleProxy ) ;
}
2018-04-13 09:19:50 +00:00
}
}