// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Layout; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; using osuTK; namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModFlashlight : ModFlashlight { public override double ScoreMultiplier => 1.12; [SettingSource("Change radius based on combo", "Decrease the flashlight radius as combo increases.")] public override BindableBool ChangeRadius { get; } = new BindableBool { Default = true, Value = true }; [SettingSource("Initial radius", "Initial radius of the flashlight area.")] public override BindableNumber InitialRadius { get; } = new BindableNumber { MinValue = 0f, MaxValue = 400f, Default = 250f, Value = 250f, Precision = 5f }; public override Flashlight CreateFlashlight() => new TaikoFlashlight(playfield, ChangeRadius.Value, InitialRadius.Value); private TaikoPlayfield playfield; public override void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { playfield = (TaikoPlayfield)drawableRuleset.Playfield; base.ApplyToDrawableRuleset(drawableRuleset); } private class TaikoFlashlight : Flashlight { private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.DrawSize); private readonly TaikoPlayfield taikoPlayfield; public TaikoFlashlight(TaikoPlayfield taikoPlayfield, bool isRadiusBasedOnCombo, float initialRadius) : base(isRadiusBasedOnCombo, initialRadius) { this.taikoPlayfield = taikoPlayfield; FlashlightSize = getSizeFor(0); AddLayout(flashlightProperties); } private Vector2 getSizeFor(int combo) { // Preserve flashlight size through the playfield's aspect adjustment. return new Vector2(0, GetRadiusFor(combo) * taikoPlayfield.DrawHeight / TaikoPlayfield.DEFAULT_HEIGHT); } protected override void OnComboChange(ValueChangedEvent e) { this.TransformTo(nameof(FlashlightSize), getSizeFor(e.NewValue), FLASHLIGHT_FADE_DURATION); } protected override string FragmentShader => "CircularFlashlight"; protected override void Update() { base.Update(); if (!flashlightProperties.IsValid) { FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre); ClearTransforms(targetMember: nameof(FlashlightSize)); FlashlightSize = getSizeFor(Combo.Value); flashlightProperties.Validate(); } } } } }