2020-03-30 22:14:30 +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.
2020-08-24 21:36:37 +08:00
using JetBrains.Annotations ;
2020-03-30 22:14:30 +08:00
using osu.Framework.Allocation ;
using osu.Framework.Bindables ;
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
using osu.Framework.Graphics.Shapes ;
using osu.Framework.Graphics.Sprites ;
using osu.Framework.Input.Bindings ;
2020-08-22 02:00:20 +08:00
using osu.Game.Rulesets.Mania.UI ;
2020-03-30 22:14:30 +08:00
using osu.Game.Rulesets.UI.Scrolling ;
using osu.Game.Skinning ;
using osuTK ;
using osuTK.Graphics ;
namespace osu.Game.Rulesets.Mania.Skinning
{
2020-03-31 17:18:53 +08:00
public class LegacyColumnBackground : LegacyManiaColumnElement , IKeyBindingHandler < ManiaAction >
2020-03-30 22:14:30 +08:00
{
private readonly IBindable < ScrollingDirection > direction = new Bindable < ScrollingDirection > ( ) ;
2020-04-02 17:39:49 +08:00
private readonly bool isLastColumn ;
2020-03-30 22:14:30 +08:00
2020-08-24 21:36:37 +08:00
[CanBeNull]
private readonly LegacyStageBackground stageBackground ;
private Container hitTargetContainer ;
2020-03-30 22:14:30 +08:00
private Container lightContainer ;
private Sprite light ;
2020-08-24 21:36:37 +08:00
private Drawable hitTarget ;
2020-03-30 22:14:30 +08:00
2020-08-22 02:00:20 +08:00
private float hitPosition ;
2020-08-24 21:36:37 +08:00
public LegacyColumnBackground ( bool isLastColumn , [ CanBeNull ] LegacyStageBackground stageBackground )
2020-03-30 22:14:30 +08:00
{
2020-04-02 17:39:49 +08:00
this . isLastColumn = isLastColumn ;
2020-08-24 21:36:37 +08:00
this . stageBackground = stageBackground ;
2020-03-30 22:14:30 +08:00
RelativeSizeAxes = Axes . Both ;
}
[BackgroundDependencyLoader]
private void load ( ISkinSource skin , IScrollingInfo scrollingInfo )
{
2020-06-20 14:53:25 +08:00
string lightImage = skin . GetManiaSkinConfig < string > ( LegacyManiaSkinConfigurationLookups . LightImage ) ? . Value
2020-03-30 22:14:30 +08:00
? ? "mania-stage-light" ;
2020-06-20 14:56:39 +08:00
float leftLineWidth = GetColumnSkinConfig < float > ( skin , LegacyManiaSkinConfigurationLookups . LeftLineWidth )
2020-03-31 19:12:02 +08:00
? . Value ? ? 1 ;
2020-06-20 14:56:39 +08:00
float rightLineWidth = GetColumnSkinConfig < float > ( skin , LegacyManiaSkinConfigurationLookups . RightLineWidth )
2020-03-31 19:12:02 +08:00
? . Value ? ? 1 ;
2020-03-30 22:14:30 +08:00
bool hasLeftLine = leftLineWidth > 0 ;
bool hasRightLine = rightLineWidth > 0 & & skin . GetConfig < LegacySkinConfiguration . LegacySetting , decimal > ( LegacySkinConfiguration . LegacySetting . Version ) ? . Value > = 2.4 m
2020-04-02 17:39:49 +08:00
| | isLastColumn ;
2020-08-24 21:36:37 +08:00
bool hasHitTarget = Column . Index = = 0 | | stageBackground = = null ;
2020-03-30 22:14:30 +08:00
2020-08-22 02:00:20 +08:00
hitPosition = GetColumnSkinConfig < float > ( skin , LegacyManiaSkinConfigurationLookups . HitPosition ) ? . Value
? ? Stage . HIT_TARGET_POSITION ;
2020-06-20 14:56:39 +08:00
float lightPosition = GetColumnSkinConfig < float > ( skin , LegacyManiaSkinConfigurationLookups . LightPosition ) ? . Value
2020-04-01 15:05:52 +08:00
? ? 0 ;
2020-06-20 14:56:39 +08:00
Color4 lineColour = GetColumnSkinConfig < Color4 > ( skin , LegacyManiaSkinConfigurationLookups . ColumnLineColour ) ? . Value
2020-04-02 17:10:17 +08:00
? ? Color4 . White ;
2020-06-20 14:56:39 +08:00
Color4 backgroundColour = GetColumnSkinConfig < Color4 > ( skin , LegacyManiaSkinConfigurationLookups . ColumnBackgroundColour ) ? . Value
2020-04-07 15:53:29 +08:00
? ? Color4 . Black ;
2020-06-20 14:56:39 +08:00
Color4 lightColour = GetColumnSkinConfig < Color4 > ( skin , LegacyManiaSkinConfigurationLookups . ColumnLightColour ) ? . Value
2020-04-07 15:53:29 +08:00
? ? Color4 . White ;
2020-08-24 21:36:37 +08:00
Drawable background ;
InternalChildren = new [ ]
2020-03-30 22:14:30 +08:00
{
2020-08-24 21:36:37 +08:00
background = new Box
2020-03-30 22:14:30 +08:00
{
RelativeSizeAxes = Axes . Both ,
2020-04-07 15:53:29 +08:00
Colour = backgroundColour
2020-03-30 22:14:30 +08:00
} ,
2020-08-24 21:36:37 +08:00
hitTargetContainer = new Container
2020-03-30 22:14:30 +08:00
{
2020-08-22 02:00:20 +08:00
RelativeSizeAxes = Axes . Both ,
Children = new [ ]
{
2020-08-24 21:36:37 +08:00
// In legacy skins, the hit target takes on the full stage size and is sandwiched between the column background and the column light.
// To simulate this effect in lazer's hierarchy, the hit target is added to the first column's background and manually extended to the full size of the stage.
// Adding to the first columns allows depth issues to be resolved - if it were added to the last column, the previous column lights would appear below it.
// This still means that the hit target will appear below the next column backgrounds, but that's a much easier problem to solve by proxying the backgrounds below.
hitTarget = new LegacyHitTarget
{
RelativeSizeAxes = Axes . Y ,
Alpha = hasHitTarget ? 1 : 0
} ,
2020-08-22 02:00:20 +08:00
new Box
{
RelativeSizeAxes = Axes . Y ,
Width = leftLineWidth ,
Scale = new Vector2 ( 0.740f , 1 ) ,
Colour = lineColour ,
Alpha = hasLeftLine ? 1 : 0
} ,
new Box
{
Anchor = Anchor . TopRight ,
Origin = Anchor . TopRight ,
RelativeSizeAxes = Axes . Y ,
Width = rightLineWidth ,
Scale = new Vector2 ( 0.740f , 1 ) ,
Colour = lineColour ,
Alpha = hasRightLine ? 1 : 0
}
}
2020-03-30 22:14:30 +08:00
} ,
lightContainer = new Container
{
Origin = Anchor . BottomCentre ,
RelativeSizeAxes = Axes . Both ,
2020-04-01 15:05:52 +08:00
Padding = new MarginPadding { Bottom = lightPosition } ,
2020-03-30 22:14:30 +08:00
Child = light = new Sprite
{
Anchor = Anchor . BottomCentre ,
Origin = Anchor . BottomCentre ,
2020-04-07 15:53:29 +08:00
Colour = lightColour ,
2020-03-30 22:14:30 +08:00
Texture = skin . GetTexture ( lightImage ) ,
RelativeSizeAxes = Axes . X ,
Width = 1 ,
Alpha = 0
}
}
} ;
2020-08-24 21:36:37 +08:00
// Resolve depth issues with the hit target appearing under the next column backgrounds by proxying to the stage background (always below the columns).
stageBackground ? . AddColumnBackground ( background . CreateProxy ( ) ) ;
2020-03-30 22:14:30 +08:00
direction . BindTo ( scrollingInfo . Direction ) ;
direction . BindValueChanged ( onDirectionChanged , true ) ;
}
private void onDirectionChanged ( ValueChangedEvent < ScrollingDirection > direction )
{
if ( direction . NewValue = = ScrollingDirection . Up )
{
lightContainer . Anchor = Anchor . TopCentre ;
lightContainer . Scale = new Vector2 ( 1 , - 1 ) ;
2020-08-22 02:00:20 +08:00
2020-08-24 21:36:37 +08:00
hitTargetContainer . Padding = new MarginPadding { Top = hitPosition } ;
2020-03-30 22:14:30 +08:00
}
else
{
lightContainer . Anchor = Anchor . BottomCentre ;
lightContainer . Scale = Vector2 . One ;
2020-08-22 02:00:20 +08:00
2020-08-24 21:36:37 +08:00
hitTargetContainer . Padding = new MarginPadding { Bottom = hitPosition } ;
2020-03-30 22:14:30 +08:00
}
}
2020-08-24 21:36:37 +08:00
protected override void Update ( )
{
base . Update ( ) ;
hitTarget . Width = stageBackground ? . DrawWidth ? ? DrawWidth ;
}
2020-03-30 22:14:30 +08:00
public bool OnPressed ( ManiaAction action )
{
2020-03-31 17:18:53 +08:00
if ( action = = Column . Action . Value )
2020-03-30 22:14:30 +08:00
{
light . FadeIn ( ) ;
light . ScaleTo ( Vector2 . One ) ;
}
return false ;
}
public void OnReleased ( ManiaAction action )
{
// Todo: Should be 400 * 100 / CurrentBPM
const double animation_length = 250 ;
2020-03-31 17:18:53 +08:00
if ( action = = Column . Action . Value )
2020-03-30 22:14:30 +08:00
{
light . FadeTo ( 0 , animation_length ) ;
light . ScaleTo ( new Vector2 ( 1 , 0 ) , animation_length ) ;
}
}
}
}