// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osuTK; namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFlashlight : ModFlashlight, IApplicableToDrawableHitObjects { public override double ScoreMultiplier => 1.12; private const float default_flashlight_size = 180; private int trackingSliders; private OsuFlashlight flashlight; public override Flashlight CreateFlashlight() => flashlight = new OsuFlashlight(); public void ApplyToDrawableHitObjects(IEnumerable drawables) { foreach (DrawableSlider drawable in drawables.OfType()) { drawable.Tracking.ValueChanged += updateTrackingSliders; } } private void updateTrackingSliders(ValueChangedEvent value) { if (value.NewValue) trackingSliders++; else trackingSliders--; flashlight.FlashlightLightness = trackingSliders > 0 ? 0.2f : 1.0f; } private class OsuFlashlight : Flashlight, IRequireHighFrequencyMousePosition { public OsuFlashlight() { FlashlightSize = new Vector2(0, getSizeFor(0)); } protected override bool OnMouseMove(MouseMoveEvent e) { FlashlightPosition = e.MousePosition; return base.OnMouseMove(e); } private float getSizeFor(int combo) { if (combo > 200) return default_flashlight_size * 0.8f; else if (combo > 100) return default_flashlight_size * 0.9f; else return default_flashlight_size; } protected override void OnComboChange(ValueChangedEvent e) { this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(e.NewValue)), FLASHLIGHT_FADE_DURATION); } protected override string FragmentShader => "CircularFlashlight"; } } }