1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-27 07:02:54 +08:00
osu-lazer/osu.Game/Skinning/LegacyHealthDisplay.cs

265 lines
8.0 KiB
C#
Raw Normal View History

2020-10-16 13:39:45 +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.
2022-06-17 15:37:17 +08:00
#nullable disable
2020-10-16 13:54:46 +08:00
using System;
2020-10-16 13:39:45 +08:00
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
2020-10-16 14:10:39 +08:00
using osu.Framework.Graphics.Textures;
2020-10-16 13:54:46 +08:00
using osu.Framework.Utils;
2020-10-16 13:39:45 +08:00
using osu.Game.Rulesets.Judgements;
using osu.Game.Screens.Play.HUD;
using osu.Game.Utils;
2020-10-16 13:39:45 +08:00
using osuTK;
2020-10-16 15:45:28 +08:00
using osuTK.Graphics;
2020-10-16 13:39:45 +08:00
namespace osu.Game.Skinning
{
public class LegacyHealthDisplay : HealthDisplay, ISkinnableDrawable
2020-10-16 13:39:45 +08:00
{
private const double epic_cutoff = 0.5;
2020-10-16 15:45:28 +08:00
private LegacyHealthPiece fill;
private LegacyHealthPiece marker;
2020-10-16 13:54:46 +08:00
private float maxFillWidth;
2020-10-16 15:18:29 +08:00
private bool isNewStyle;
2020-10-16 14:10:39 +08:00
public bool UsesFixedAnchor { get; set; }
2020-10-16 13:39:45 +08:00
[BackgroundDependencyLoader]
private void load(ISkinSource source)
2020-10-16 13:39:45 +08:00
{
AutoSizeAxes = Axes.Both;
var skin = source.FindProvider(s => getTexture(s, "bg") != null);
// the marker lookup to decide which display style must be performed on the source of the bg, which is the most common element.
2020-10-16 15:18:29 +08:00
isNewStyle = getTexture(skin, "marker") != null;
// background implementation is the same for both versions.
AddInternal(new Sprite { Texture = getTexture(skin, "bg") });
2020-10-16 14:10:39 +08:00
2020-10-16 15:18:29 +08:00
if (isNewStyle)
2020-10-16 13:39:45 +08:00
{
2020-10-16 15:18:29 +08:00
AddRangeInternal(new[]
2020-10-16 13:39:45 +08:00
{
2020-10-16 15:18:29 +08:00
fill = new LegacyNewStyleFill(skin),
marker = new LegacyNewStyleMarker(skin),
});
}
else
{
AddRangeInternal(new[]
2020-10-16 13:39:45 +08:00
{
2020-10-16 15:18:29 +08:00
fill = new LegacyOldStyleFill(skin),
marker = new LegacyOldStyleMarker(skin),
});
}
2020-10-16 13:39:45 +08:00
2020-10-16 15:45:28 +08:00
fill.Current.BindTo(Current);
2020-10-16 15:18:29 +08:00
marker.Current.BindTo(Current);
2020-10-16 15:45:28 +08:00
2020-10-16 13:54:46 +08:00
maxFillWidth = fill.Width;
2020-10-16 13:39:45 +08:00
}
protected override void Update()
{
base.Update();
2020-10-16 13:54:46 +08:00
fill.Width = Interpolation.ValueAt(
Math.Clamp(Clock.ElapsedFrameTime, 0, 200),
fill.Width, (float)Current.Value * maxFillWidth, 0, 200, Easing.OutQuint);
marker.Position = fill.Position + new Vector2(fill.DrawWidth, isNewStyle ? fill.DrawHeight / 2 : 0);
2020-10-16 13:39:45 +08:00
}
protected override void Flash(JudgementResult result) => marker.Flash(result);
2020-10-16 15:18:29 +08:00
private static Texture getTexture(ISkin skin, string name) => skin?.GetTexture($"scorebar-{name}");
2020-10-16 15:18:29 +08:00
2020-10-16 15:45:28 +08:00
private static Color4 getFillColour(double hp)
{
if (hp < 0.2)
return LegacyUtils.InterpolateNonLinear(0.2 - hp, Color4.Black, Color4.Red, 0, 0.2);
2020-10-16 15:45:28 +08:00
if (hp < epic_cutoff)
return LegacyUtils.InterpolateNonLinear(0.5 - hp, Color4.White, Color4.Black, 0, 0.5);
2020-10-16 15:45:28 +08:00
return Color4.White;
}
2020-10-16 16:09:00 +08:00
public class LegacyOldStyleMarker : LegacyMarker
2020-10-16 15:18:29 +08:00
{
private readonly Texture normalTexture;
private readonly Texture dangerTexture;
private readonly Texture superDangerTexture;
public LegacyOldStyleMarker(ISkin skin)
2020-10-16 15:18:29 +08:00
{
normalTexture = getTexture(skin, "ki");
dangerTexture = getTexture(skin, "kidanger");
superDangerTexture = getTexture(skin, "kidanger2");
2020-10-16 15:18:29 +08:00
}
2020-10-16 16:09:00 +08:00
public override Sprite CreateSprite() => new Sprite
{
Texture = normalTexture,
Origin = Anchor.Centre,
};
protected override void LoadComplete()
{
base.LoadComplete();
Current.BindValueChanged(hp =>
{
if (hp.NewValue < 0.2f)
2020-10-16 16:09:00 +08:00
Main.Texture = superDangerTexture;
else if (hp.NewValue < epic_cutoff)
2020-10-16 16:09:00 +08:00
Main.Texture = dangerTexture;
else
2020-10-16 16:09:00 +08:00
Main.Texture = normalTexture;
});
}
2020-10-16 15:18:29 +08:00
}
2020-10-16 16:09:00 +08:00
public class LegacyNewStyleMarker : LegacyMarker
2020-10-16 13:39:45 +08:00
{
private readonly ISkin skin;
2020-10-16 15:45:28 +08:00
public LegacyNewStyleMarker(ISkin skin)
2020-10-16 15:18:29 +08:00
{
2020-10-16 16:09:00 +08:00
this.skin = skin;
2020-10-16 15:18:29 +08:00
}
2020-10-16 13:39:45 +08:00
2020-10-16 16:09:00 +08:00
public override Sprite CreateSprite() => new Sprite
{
Texture = getTexture(skin, "marker"),
Origin = Anchor.Centre,
};
2020-10-16 15:45:28 +08:00
protected override void Update()
2020-10-16 13:39:45 +08:00
{
2020-10-16 15:45:28 +08:00
base.Update();
2020-10-16 16:09:00 +08:00
Main.Colour = getFillColour(Current.Value);
Main.Blending = Current.Value < epic_cutoff ? BlendingParameters.Inherit : BlendingParameters.Additive;
2020-10-16 15:18:29 +08:00
}
}
internal abstract class LegacyFill : LegacyHealthPiece
2020-10-16 15:18:29 +08:00
{
protected LegacyFill(ISkin skin)
2020-10-16 15:18:29 +08:00
{
// required for sizing correctly..
var firstFrame = getTexture(skin, "colour-0");
2020-10-16 13:39:45 +08:00
2020-10-16 15:18:29 +08:00
if (firstFrame == null)
2020-10-16 13:39:45 +08:00
{
2020-10-16 15:18:29 +08:00
InternalChild = new Sprite { Texture = getTexture(skin, "colour") };
Size = InternalChild.Size;
2020-10-16 13:39:45 +08:00
}
else
{
2021-06-11 20:03:21 +08:00
InternalChild = skin.GetAnimation("scorebar-colour", true, true, startAtCurrentTime: false, applyConfigFrameRate: true) ?? Empty();
2020-10-16 15:18:29 +08:00
Size = new Vector2(firstFrame.DisplayWidth, firstFrame.DisplayHeight);
2020-10-16 13:39:45 +08:00
}
2020-10-16 15:18:29 +08:00
Masking = true;
2020-10-16 13:39:45 +08:00
}
}
2020-10-16 14:10:39 +08:00
internal class LegacyOldStyleFill : LegacyFill
2020-10-16 15:18:29 +08:00
{
public LegacyOldStyleFill(ISkin skin)
: base(skin)
2020-10-16 15:18:29 +08:00
{
Position = new Vector2(3, 10) * 1.6f;
}
}
2020-10-16 15:45:28 +08:00
internal class LegacyNewStyleFill : LegacyFill
{
public LegacyNewStyleFill(ISkin skin)
: base(skin)
{
2020-10-16 15:18:29 +08:00
Position = new Vector2(7.5f, 7.8f) * 1.6f;
2020-10-16 15:45:28 +08:00
}
protected override void Update()
{
base.Update();
2020-10-16 16:09:00 +08:00
Colour = getFillColour(Current.Value);
}
}
public abstract class LegacyMarker : LegacyHealthPiece
{
protected Sprite Main;
private Sprite explode;
protected LegacyMarker()
{
Origin = Anchor.Centre;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
Main = CreateSprite(),
explode = CreateSprite().With(s =>
{
s.Alpha = 0;
s.Blending = BlendingParameters.Additive;
}),
};
}
public abstract Sprite CreateSprite();
protected override void LoadComplete()
{
base.LoadComplete();
Current.BindValueChanged(val =>
{
if (val.NewValue > val.OldValue)
bulgeMain();
});
2020-10-16 15:45:28 +08:00
}
2020-10-16 16:09:00 +08:00
public override void Flash(JudgementResult result)
{
bulgeMain();
bool isEpic = Current.Value >= epic_cutoff;
explode.Blending = isEpic ? BlendingParameters.Additive : BlendingParameters.Inherit;
explode.ScaleTo(1).Then().ScaleTo(isEpic ? 2 : 1.6f, 120);
2020-10-16 16:09:00 +08:00
explode.FadeOutFromOne(120);
}
private void bulgeMain() =>
Main.ScaleTo(1.4f).Then().ScaleTo(1, 200, Easing.Out);
2020-10-16 15:45:28 +08:00
}
public class LegacyHealthPiece : CompositeDrawable
2020-10-16 15:45:28 +08:00
{
public Bindable<double> Current { get; } = new Bindable<double>();
public virtual void Flash(JudgementResult result)
{
2020-10-16 15:18:29 +08:00
}
}
2020-10-16 13:39:45 +08:00
}
}