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
2020-08-27 19:24:08 +08:00
using System ;
2018-07-02 11:31:41 +08:00
using JetBrains.Annotations ;
2018-06-08 19:13:24 +08:00
using osu.Framework.Allocation ;
2019-02-21 18:04:31 +08:00
using osu.Framework.Bindables ;
2018-04-13 17:19:50 +08:00
using osu.Framework.Graphics ;
2021-05-11 15:08:25 +08:00
using osu.Game.Audio ;
2018-04-13 17:19:50 +08:00
using osu.Game.Rulesets.Objects.Drawables ;
2018-06-08 14:16:45 +08:00
using osu.Game.Rulesets.UI.Scrolling ;
2020-04-12 07:33:25 +08:00
using osu.Game.Rulesets.Mania.UI ;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
2018-07-02 11:31:41 +08:00
public abstract class DrawableManiaHitObject : DrawableHitObject < ManiaHitObject >
2018-04-13 17:19:50 +08:00
{
/// <summary>
2018-07-02 11:31:41 +08:00
/// The <see cref="ManiaAction"/> which causes this <see cref="DrawableManiaHitObject{TObject}"/> to be hit.
2018-04-13 17:19:50 +08:00
/// </summary>
2018-07-02 11:31:41 +08:00
protected readonly IBindable < ManiaAction > Action = new Bindable < ManiaAction > ( ) ;
2018-04-13 17:19:50 +08:00
2018-06-08 20:41:20 +08:00
protected readonly IBindable < ScrollingDirection > Direction = new Bindable < ScrollingDirection > ( ) ;
2020-04-13 12:01:27 +08:00
[Resolved(canBeNull: true)]
2020-04-13 12:42:21 +08:00
private ManiaPlayfield playfield { get ; set ; }
2020-04-13 12:01:27 +08:00
2021-05-11 15:08:25 +08:00
/// <summary>
/// Gets the samples that are played by this object during gameplay.
/// </summary>
public ISampleInfo [ ] GetGameplaySamples ( ) = > Samples . Samples ;
2020-04-13 12:00:03 +08:00
protected override float SamplePlaybackPosition
2020-04-12 07:33:25 +08:00
{
get
{
2020-04-13 12:42:21 +08:00
if ( playfield = = null )
2020-04-13 12:01:27 +08:00
return base . SamplePlaybackPosition ;
2020-04-12 07:33:25 +08:00
2020-04-13 12:42:21 +08:00
return ( float ) HitObject . Column / playfield . TotalColumns ;
2020-04-12 07:33:25 +08:00
}
}
2020-08-31 12:33:41 +08:00
/// <summary>
/// Whether this <see cref="DrawableManiaHitObject"/> can be hit, given a time value.
2020-08-31 18:02:02 +08:00
/// If non-null, judgements will be ignored whilst the function returns false.
2020-08-31 12:33:41 +08:00
/// </summary>
2020-08-27 19:24:08 +08:00
public Func < DrawableHitObject , double , bool > CheckHittable ;
2018-07-02 11:31:41 +08:00
protected DrawableManiaHitObject ( ManiaHitObject hitObject )
2018-04-13 17:19:50 +08:00
: base ( hitObject )
{
2021-05-12 15:35:05 +08:00
RelativeSizeAxes = Axes . X ;
2018-04-13 17:19:50 +08:00
}
2018-06-07 13:27:59 +08:00
2018-07-02 11:31:41 +08:00
[BackgroundDependencyLoader(true)]
private void load ( [ CanBeNull ] IBindable < ManiaAction > action , [ NotNull ] IScrollingInfo scrollingInfo )
2018-06-08 20:41:20 +08:00
{
2018-07-02 11:31:41 +08:00
if ( action ! = null )
Action . BindTo ( action ) ;
2018-06-08 20:41:20 +08:00
Direction . BindTo ( scrollingInfo . Direction ) ;
2021-05-12 15:40:46 +08:00
}
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2018-06-08 20:41:20 +08:00
Direction . BindValueChanged ( OnDirectionChanged , true ) ;
}
2021-05-12 15:35:05 +08:00
protected override void OnApply ( )
{
base . OnApply ( ) ;
if ( ParentHitObject ! = null )
AccentColour . BindTo ( ParentHitObject . AccentColour ) ;
}
protected override void OnFree ( )
{
base . OnFree ( ) ;
if ( ParentHitObject ! = null )
AccentColour . UnbindFrom ( ParentHitObject . AccentColour ) ;
}
2020-04-28 14:34:10 +08:00
private double computedLifetimeStart ;
public override double LifetimeStart
{
get = > base . LifetimeStart ;
set
{
computedLifetimeStart = value ;
if ( ! AlwaysAlive )
base . LifetimeStart = value ;
}
}
private double computedLifetimeEnd ;
public override double LifetimeEnd
{
get = > base . LifetimeEnd ;
set
{
computedLifetimeEnd = value ;
if ( ! AlwaysAlive )
base . LifetimeEnd = value ;
}
}
private bool alwaysAlive ;
/// <summary>
/// Whether this <see cref="DrawableManiaHitObject"/> should always remain alive.
/// </summary>
internal bool AlwaysAlive
{
get = > alwaysAlive ;
set
{
if ( alwaysAlive = = value )
return ;
alwaysAlive = value ;
if ( value )
{
// Set the base lifetimes directly, to avoid mangling the computed lifetimes
base . LifetimeStart = double . MinValue ;
base . LifetimeEnd = double . MaxValue ;
}
else
{
LifetimeStart = computedLifetimeStart ;
LifetimeEnd = computedLifetimeEnd ;
}
}
}
2018-11-26 10:34:25 +08:00
2019-02-21 17:56:34 +08:00
protected virtual void OnDirectionChanged ( ValueChangedEvent < ScrollingDirection > e )
2018-06-08 19:13:24 +08:00
{
2019-02-21 17:56:34 +08:00
Anchor = Origin = e . NewValue = = ScrollingDirection . Up ? Anchor . TopCentre : Anchor . BottomCentre ;
2018-06-08 19:13:24 +08:00
}
2019-07-22 14:55:38 +08:00
2020-11-04 15:19:07 +08:00
protected override void UpdateHitStateTransforms ( ArmedState state )
2018-06-07 13:27:59 +08:00
{
switch ( state )
{
case ArmedState . Miss :
2019-09-12 18:29:08 +08:00
this . FadeOut ( 150 , Easing . In ) ;
2018-06-07 13:27:59 +08:00
break ;
2019-04-01 11:44:46 +08:00
2018-06-07 13:27:59 +08:00
case ArmedState . Hit :
2020-08-21 22:56:27 +08:00
this . FadeOut ( ) ;
2018-06-07 13:27:59 +08:00
break ;
}
}
2020-08-27 19:24:08 +08:00
/// <summary>
/// Causes this <see cref="DrawableManiaHitObject"/> to get missed, disregarding all conditions in implementations of <see cref="DrawableHitObject.CheckForResult"/>.
/// </summary>
2020-10-03 04:58:10 +08:00
public void MissForcefully ( ) = > ApplyResult ( r = > r . Type = r . Judgement . MinResult ) ;
2018-04-13 17:19:50 +08:00
}
2019-08-27 03:06:30 +08:00
public abstract class DrawableManiaHitObject < TObject > : DrawableManiaHitObject
where TObject : ManiaHitObject
{
2021-05-12 15:35:05 +08:00
public new TObject HitObject = > ( TObject ) base . HitObject ;
2019-08-27 03:06:30 +08:00
protected DrawableManiaHitObject ( TObject hitObject )
: base ( hitObject )
{
}
}
2018-04-13 17:19:50 +08:00
}