osu/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

92 lines
3.4 KiB
C#
Raw Normal View History

// 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-10-18 11:39:40 +00:00
using System;
2022-08-18 17:00:54 +00:00
using System.Linq;
2022-10-18 11:39:40 +00:00
using osu.Framework.Graphics;
2022-09-07 23:21:03 +00:00
using osu.Framework.Localisation;
2022-08-18 17:00:54 +00:00
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
2022-10-18 11:39:40 +00:00
using osu.Game.Rulesets.Objects.Drawables;
2022-08-18 17:00:54 +00:00
using osu.Game.Rulesets.Osu.Objects;
2022-10-18 11:39:40 +00:00
using osu.Game.Rulesets.Osu.Objects.Drawables;
2022-08-18 17:00:54 +00:00
namespace osu.Game.Rulesets.Osu.Mods
{
2022-10-18 11:39:40 +00:00
public class OsuModFreezeFrame : Mod, IApplicableToDrawableHitObject, IApplicableToBeatmap
2022-08-18 17:00:54 +00:00
{
public override string Name => "Freeze Frame";
2022-09-07 22:05:48 +00:00
public override string Acronym => "FR";
2022-09-07 22:05:48 +00:00
public override double ScoreMultiplier => 1;
public override LocalisableString Description => "Burn the notes into your memory.";
2022-09-07 22:05:48 +00:00
2022-10-18 11:39:40 +00:00
//Alters the transforms of the approach circles, breaking the effects of these mods.
2022-10-25 06:48:45 +00:00
public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent) };
2022-10-18 11:39:40 +00:00
2022-08-18 17:00:54 +00:00
public override ModType Type => ModType.Fun;
2022-09-07 22:05:48 +00:00
2022-10-18 11:39:40 +00:00
//mod breaks normal approach circle preempt
private double originalPreempt;
2022-09-08 09:14:56 +00:00
public void ApplyToBeatmap(IBeatmap beatmap)
2022-08-18 17:00:54 +00:00
{
var firstHitObject = beatmap.HitObjects.OfType<OsuHitObject>().FirstOrDefault();
if (firstHitObject == null)
return;
double lastNewComboTime = 0;
originalPreempt = firstHitObject.TimePreempt;
2022-08-18 17:00:54 +00:00
2022-09-07 23:21:03 +00:00
foreach (var obj in beatmap.HitObjects.OfType<OsuHitObject>())
2022-08-18 17:00:54 +00:00
{
if (obj.NewCombo) { lastNewComboTime = obj.StartTime; }
2022-09-07 23:21:03 +00:00
applyFadeInAdjustment(obj);
2022-08-18 17:00:54 +00:00
}
void applyFadeInAdjustment(OsuHitObject osuObject)
2022-09-16 00:57:21 +00:00
{
osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime;
2022-09-16 00:57:21 +00:00
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
{
switch (nested)
{
//Freezing the SliderTicks doesnt play well with snaking sliders
case SliderTick:
//SliderRepeat wont layer correctly if preempt is changed.
case SliderRepeat:
2022-10-12 17:45:08 +00:00
break;
default:
applyFadeInAdjustment(nested);
break;
}
}
2022-09-16 00:57:21 +00:00
}
}
2022-10-18 11:39:40 +00:00
public void ApplyToDrawableHitObject(DrawableHitObject drawableObject)
{
drawableObject.ApplyCustomUpdateState += (drawableHitObject, _) =>
{
if (drawableHitObject is not DrawableHitCircle drawableHitCircle) return;
var hitCircle = drawableHitCircle.HitObject;
var approachCircle = drawableHitCircle.ApproachCircle;
2022-10-25 04:27:26 +00:00
// Reapply scale, ensuring the AR isn't changed due to the new preempt.
approachCircle.ClearTransforms(targetMember: nameof(approachCircle.Scale));
approachCircle.ScaleTo(4 * (float)(hitCircle.TimePreempt / originalPreempt));
2022-10-18 11:39:40 +00:00
using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - hitCircle.TimePreempt))
approachCircle.ScaleTo(1, hitCircle.TimePreempt).Then().Expire();
2022-10-18 11:39:40 +00:00
};
}
2022-08-18 17:00:54 +00:00
}
}