2022-09-19 03:08:34 +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-09-19 03:10:01 +08:00
|
|
|
|
using System;
|
|
|
|
|
using osu.Framework.Graphics;
|
2022-09-19 13:06:07 +08:00
|
|
|
|
using osu.Framework.Utils;
|
2022-09-19 03:08:34 +08:00
|
|
|
|
using osu.Game.Skinning;
|
2022-09-19 13:06:07 +08:00
|
|
|
|
using osuTK;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
using osuTK.Graphics;
|
2022-09-19 03:08:34 +08:00
|
|
|
|
|
|
|
|
|
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|
|
|
|
{
|
|
|
|
|
public class LegacySmoke : Smoke
|
|
|
|
|
{
|
2022-09-19 13:06:07 +08:00
|
|
|
|
// fade values
|
|
|
|
|
private const double initial_fade_out_duration = 4000;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
|
|
|
|
private const double re_fade_in_speed = 3;
|
|
|
|
|
private const double re_fade_in_duration = 50;
|
|
|
|
|
|
2022-09-19 13:06:07 +08:00
|
|
|
|
private const double final_fade_out_speed = 2;
|
|
|
|
|
private const double final_fade_out_duration = 8000;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
2022-09-19 13:06:07 +08:00
|
|
|
|
private const float initial_alpha = 0.6f;
|
|
|
|
|
private const float re_fade_in_alpha = 1f;
|
|
|
|
|
|
|
|
|
|
// scale values
|
|
|
|
|
private const double scale_duration = 1200;
|
|
|
|
|
|
|
|
|
|
private const float initial_scale = 0.65f;
|
|
|
|
|
private const float final_scale = 1f;
|
|
|
|
|
|
|
|
|
|
// rotation values
|
|
|
|
|
private const double rotation_duration = 500;
|
|
|
|
|
|
|
|
|
|
private const float max_rotation = 0.25f;
|
|
|
|
|
|
2022-09-20 19:59:58 +08:00
|
|
|
|
protected int RotationSeed { get; set; } = RNG.Next();
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
2022-09-21 00:44:01 +08:00
|
|
|
|
public override double LifetimeEnd
|
2022-09-19 03:10:01 +08:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
double initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime);
|
2022-09-21 00:44:01 +08:00
|
|
|
|
return SmokeEndTime + final_fade_out_duration + initialFadeOutDurationTrunc / re_fade_in_speed + initialFadeOutDurationTrunc / final_fade_out_speed;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-19 09:32:33 +08:00
|
|
|
|
private readonly ISkin skin;
|
2022-09-19 03:08:34 +08:00
|
|
|
|
|
|
|
|
|
public LegacySmoke(ISkin skin)
|
|
|
|
|
{
|
|
|
|
|
this.skin = skin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void LoadComplete()
|
|
|
|
|
{
|
|
|
|
|
base.LoadComplete();
|
|
|
|
|
|
|
|
|
|
Texture = skin.GetTexture("cursor-smoke");
|
|
|
|
|
}
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
|
|
|
|
protected override DrawNode CreateDrawNode() => new LegacySmokeDrawNode(this);
|
|
|
|
|
|
|
|
|
|
protected class LegacySmokeDrawNode : SmokeDrawNode
|
|
|
|
|
{
|
2022-09-19 13:06:07 +08:00
|
|
|
|
protected new LegacySmoke Source => (LegacySmoke)base.Source;
|
|
|
|
|
|
2022-09-19 03:10:01 +08:00
|
|
|
|
private double initialFadeOutDurationTrunc;
|
|
|
|
|
private double initialFadeOutTime;
|
|
|
|
|
private double reFadeInTime;
|
|
|
|
|
private double finalFadeOutTime;
|
|
|
|
|
|
2022-09-19 13:06:07 +08:00
|
|
|
|
private int rotationSeed;
|
|
|
|
|
private Random rotationRNG = new Random();
|
|
|
|
|
|
2022-09-19 03:10:01 +08:00
|
|
|
|
public LegacySmokeDrawNode(ITexturedShaderDrawable source)
|
|
|
|
|
: base(source)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void ApplyState()
|
|
|
|
|
{
|
|
|
|
|
base.ApplyState();
|
|
|
|
|
|
|
|
|
|
initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime);
|
2022-09-19 13:06:07 +08:00
|
|
|
|
rotationSeed = Source.RotationSeed;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
2022-09-19 13:06:07 +08:00
|
|
|
|
rotationRNG = new Random(rotationSeed);
|
2022-09-19 03:10:01 +08:00
|
|
|
|
initialFadeOutTime = Math.Min(CurrentTime, SmokeEndTime);
|
|
|
|
|
reFadeInTime = re_fade_in_speed * (CurrentTime - SmokeEndTime) + SmokeEndTime - initialFadeOutDurationTrunc;
|
2022-09-19 13:06:07 +08:00
|
|
|
|
finalFadeOutTime = final_fade_out_speed * (CurrentTime - SmokeEndTime) + SmokeEndTime - initialFadeOutDurationTrunc * (1 + 1 / re_fade_in_speed);
|
2022-09-19 03:10:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-20 19:39:12 +08:00
|
|
|
|
protected override Color4 PointColour(SmokePoint point)
|
2022-09-19 03:10:01 +08:00
|
|
|
|
{
|
|
|
|
|
var color = Color4.White;
|
|
|
|
|
|
2022-09-19 13:06:07 +08:00
|
|
|
|
double timeDoingInitialFadeOut = initialFadeOutTime - point.Time;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
|
|
|
|
if (timeDoingInitialFadeOut > 0)
|
|
|
|
|
{
|
|
|
|
|
float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1);
|
|
|
|
|
color.A = (1 - fraction) * initial_alpha;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (color.A > 0)
|
|
|
|
|
{
|
2022-09-19 13:06:07 +08:00
|
|
|
|
double timeDoingReFadeIn = reFadeInTime - point.Time;
|
|
|
|
|
double timeDoingFinalFadeOut = finalFadeOutTime - point.Time;
|
2022-09-19 03:10:01 +08:00
|
|
|
|
|
|
|
|
|
if (timeDoingFinalFadeOut > 0)
|
|
|
|
|
{
|
|
|
|
|
float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1);
|
|
|
|
|
fraction = MathF.Pow(fraction, 5);
|
|
|
|
|
color.A = (1 - fraction) * re_fade_in_alpha;
|
|
|
|
|
}
|
|
|
|
|
else if (timeDoingReFadeIn > 0)
|
|
|
|
|
{
|
|
|
|
|
float fraction = Math.Clamp((float)(timeDoingReFadeIn / re_fade_in_duration), 0, 1);
|
|
|
|
|
fraction = 1 - MathF.Pow(1 - fraction, 5);
|
|
|
|
|
color.A = fraction * (re_fade_in_alpha - color.A) + color.A;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return color;
|
|
|
|
|
}
|
2022-09-19 13:06:07 +08:00
|
|
|
|
|
|
|
|
|
protected override float PointScale(SmokePoint point)
|
|
|
|
|
{
|
|
|
|
|
double timeDoingScale = CurrentTime - point.Time;
|
|
|
|
|
float fraction = Math.Clamp((float)(timeDoingScale / scale_duration), 0, 1);
|
|
|
|
|
fraction = 1 - MathF.Pow(1 - fraction, 5);
|
|
|
|
|
return fraction * (final_scale - initial_scale) + initial_scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override Vector2 PointDirection(SmokePoint point)
|
|
|
|
|
{
|
|
|
|
|
float initialAngle = MathF.Atan2(point.Direction.Y, point.Direction.X);
|
|
|
|
|
float finalAngle = initialAngle + nextRotation();
|
|
|
|
|
|
|
|
|
|
double timeDoingRotation = CurrentTime - point.Time;
|
|
|
|
|
float fraction = Math.Clamp((float)(timeDoingRotation / rotation_duration), 0, 1);
|
|
|
|
|
fraction = 1 - MathF.Pow(1 - fraction, 5);
|
|
|
|
|
float angle = fraction * (finalAngle - initialAngle) + initialAngle;
|
|
|
|
|
|
2022-09-19 15:07:22 +08:00
|
|
|
|
return new Vector2(MathF.Sin(angle), -MathF.Cos(angle));
|
2022-09-19 13:06:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private float nextRotation() => max_rotation * ((float)rotationRNG.NextDouble() * 2 - 1);
|
2022-09-19 03:10:01 +08:00
|
|
|
|
}
|
2022-09-19 03:08:34 +08:00
|
|
|
|
}
|
|
|
|
|
}
|