From 2cffce805aef4f2430328b8c39f6262c94cfe362 Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 7 Nov 2018 00:48:54 +0100 Subject: [PATCH 01/12] add flashlight mod --- .../Mods/OsuModFlashlight.cs | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs index a337439593..b6e16ff537 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -1,12 +1,94 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Framework.Input; +using osu.Framework.Input.Events; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.UI; +using OpenTK; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlashlight : ModFlashlight + public class OsuModFlashlight : ModFlashlight, IApplicableToRulesetContainer { public override double ScoreMultiplier => 1.12; + + public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + rulesetContainer.KeyBindingInputManager.Add(new Flashlight + { + RelativeSizeAxes = Axes.Both, + }); + } + + private class Flashlight : Drawable, IRequireHighFrequencyMousePosition + { + private Shader shader; + private readonly MousePositionWrapper mousePosWrapper = new MousePositionWrapper(); + + protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); + + protected override void ApplyDrawNode(DrawNode node) + { + base.ApplyDrawNode(node); + + var flashNode = (FlashlightDrawNode)node; + + flashNode.Shader = shader; + flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; + flashNode.MousePosWrapper = mousePosWrapper; + flashNode.FlashlightSize = 100f; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaderManager) + { + shader = shaderManager.Load(VertexShaderDescriptor.POSITION, "Flashlight"); + } + + protected override bool OnMouseMove(MouseMoveEvent e) + { + mousePosWrapper.MousePosition = e.ScreenSpaceMousePosition; + return base.OnMouseMove(e); + } + } + + private class MousePositionWrapper + { + public Vector2 MousePosition; + } + + private class FlashlightDrawNode : DrawNode + { + public Shader Shader; + public Quad ScreenSpaceDrawQuad; + public MousePositionWrapper MousePosWrapper; + public float FlashlightSize; + private bool sizeSet; + + public override void Draw(Action vertexAction) + { + base.Draw(vertexAction); + + Shader.Bind(); + // ReSharper disable once AssignmentInConditionalExpression + if(sizeSet = !sizeSet) + Shader.GetUniform("flashlightSize").UpdateValue(ref FlashlightSize); + + Shader.GetUniform("mousePos").UpdateValue(ref MousePosWrapper.MousePosition); + + Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); + + Shader.Unbind(); + } + } } } From 5c09662c14640543616937680b00a4da7427f75c Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 7 Nov 2018 23:40:33 +0100 Subject: [PATCH 02/12] Allow flashlight size to be variant --- osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs index b6e16ff537..c6b6d67ce6 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -32,7 +32,10 @@ namespace osu.Game.Rulesets.Osu.Mods private class Flashlight : Drawable, IRequireHighFrequencyMousePosition { private Shader shader; - private readonly MousePositionWrapper mousePosWrapper = new MousePositionWrapper(); + private readonly MousePositionWrapper mousePosWrapper = new MousePositionWrapper + { + FlashlightSize = 300f + }; protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); @@ -45,7 +48,6 @@ namespace osu.Game.Rulesets.Osu.Mods flashNode.Shader = shader; flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; flashNode.MousePosWrapper = mousePosWrapper; - flashNode.FlashlightSize = 100f; } [BackgroundDependencyLoader] @@ -64,6 +66,8 @@ namespace osu.Game.Rulesets.Osu.Mods private class MousePositionWrapper { public Vector2 MousePosition; + public float FlashlightSize; + public bool FlashlightUniformUpdated; } private class FlashlightDrawNode : DrawNode @@ -71,8 +75,6 @@ namespace osu.Game.Rulesets.Osu.Mods public Shader Shader; public Quad ScreenSpaceDrawQuad; public MousePositionWrapper MousePosWrapper; - public float FlashlightSize; - private bool sizeSet; public override void Draw(Action vertexAction) { @@ -80,8 +82,8 @@ namespace osu.Game.Rulesets.Osu.Mods Shader.Bind(); // ReSharper disable once AssignmentInConditionalExpression - if(sizeSet = !sizeSet) - Shader.GetUniform("flashlightSize").UpdateValue(ref FlashlightSize); + if(MousePosWrapper.FlashlightUniformUpdated = !MousePosWrapper.FlashlightUniformUpdated) + Shader.GetUniform("flashlightSize").UpdateValue(ref MousePosWrapper.FlashlightSize); Shader.GetUniform("mousePos").UpdateValue(ref MousePosWrapper.MousePosition); From cc8531790a127c03619cb324a0146e6817d22051 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 9 Nov 2018 13:58:46 +0900 Subject: [PATCH 03/12] Use bindables for hitobject events --- .../HitCircles/Components/HitCirclePiece.cs | 17 ++++--- .../Components/PathControlPointVisualiser.cs | 13 +++++- .../Sliders/Components/SliderBodyPiece.cs | 13 ++++-- .../Sliders/Components/SliderCirclePiece.cs | 12 ++++- .../Spinners/Components/SpinnerPiece.cs | 21 ++++++--- .../Objects/Drawables/DrawableHitCircle.cs | 20 +++++++-- .../Objects/Drawables/DrawableSlider.cs | 31 ++++++++----- .../Objects/Drawables/DrawableSliderHead.cs | 16 +++++-- .../Objects/Drawables/DrawableSliderTail.cs | 12 +++-- .../Objects/Drawables/DrawableSpinner.cs | 34 +++++++------- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 45 +++++-------------- osu.Game.Rulesets.Osu/Objects/Slider.cs | 12 +++-- 12 files changed, 150 insertions(+), 96 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs index 9c33435285..89d1b1fc46 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -13,6 +14,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components { public class HitCirclePiece : CompositeDrawable { + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable stackHeightBindable = new Bindable(); + private readonly IBindable scaleBindable = new Bindable(); + private readonly HitCircle hitCircle; public HitCirclePiece(HitCircle hitCircle) @@ -25,10 +30,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components CornerRadius = Size.X / 2; InternalChild = new RingPiece(); - - hitCircle.PositionChanged += _ => UpdatePosition(); - hitCircle.StackHeightChanged += _ => UpdatePosition(); - hitCircle.ScaleChanged += _ => Scale = new Vector2(hitCircle.Scale); } [BackgroundDependencyLoader] @@ -36,7 +37,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components { Colour = colours.Yellow; - UpdatePosition(); + positionBindable.BindValueChanged(_ => UpdatePosition()); + stackHeightBindable.BindValueChanged(_ => UpdatePosition()); + scaleBindable.BindValueChanged(v => Scale = new Vector2(v)); + + positionBindable.BindTo(hitCircle.PositionBindable); + stackHeightBindable.BindTo(hitCircle.StackHeightBindable); + scaleBindable.BindTo(hitCircle.ScaleBindable); } protected virtual void UpdatePosition() => Position = hitCircle.StackedPosition; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index db8e879126..2f3fe241e7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -1,14 +1,19 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Osu.Objects; +using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class PathControlPointVisualiser : CompositeDrawable { + private readonly IBindable controlPointsBindable = new Bindable(); + private readonly Slider slider; private readonly Container pieces; @@ -18,9 +23,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components this.slider = slider; InternalChild = pieces = new Container { RelativeSizeAxes = Axes.Both }; + } - slider.ControlPointsChanged += _ => updatePathControlPoints(); - updatePathControlPoints(); + [BackgroundDependencyLoader] + private void load() + { + controlPointsBindable.BindValueChanged(_ => updatePathControlPoints()); + controlPointsBindable.BindTo(slider.ControlPointsBindable); } private void updatePathControlPoints() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index 6fc7d39e6c..206e337ab7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Osu.Objects; @@ -14,6 +15,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class SliderBodyPiece : CompositeDrawable { + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable scaleBindable = new Bindable(); + private readonly Slider slider; private readonly ManualSliderBody body; @@ -26,9 +30,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components AccentColour = Color4.Transparent, PathWidth = slider.Scale * 64 }; - - slider.PositionChanged += _ => updatePosition(); - slider.ScaleChanged += _ => body.PathWidth = slider.Scale * 64; } [BackgroundDependencyLoader] @@ -36,7 +37,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { body.BorderColour = colours.Yellow; - updatePosition(); + positionBindable.BindValueChanged(_ => updatePosition()); + scaleBindable.BindValueChanged(v => body.PathWidth = v * 64); + + positionBindable.BindTo(slider.PositionBindable); + scaleBindable.BindTo(slider.ScaleBindable); } private void updatePosition() => Position = slider.StackedPosition; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs index a91739737f..17e823603f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs @@ -1,13 +1,18 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Objects; +using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class SliderCirclePiece : HitCirclePiece { + private readonly IBindable controlPointsBindable = new Bindable(); + private readonly Slider slider; private readonly SliderPosition position; @@ -16,8 +21,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { this.slider = slider; this.position = position; + } - slider.ControlPointsChanged += _ => UpdatePosition(); + [BackgroundDependencyLoader] + private void load() + { + controlPointsBindable.BindValueChanged(_ => UpdatePosition()); + controlPointsBindable.BindTo(slider.ControlPointsBindable); } protected override void UpdatePosition() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs index bd63a3e607..d6104a5926 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,8 +15,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components { public class SpinnerPiece : CompositeDrawable { + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable stackHeightBindable = new Bindable(); + private readonly IBindable scaleBindable = new Bindable(); + private readonly Spinner spinner; private readonly CircularContainer circle; + private readonly RingPiece ring; public SpinnerPiece(Spinner spinner) { @@ -27,7 +33,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components FillMode = FillMode.Fit; Size = new Vector2(1.3f); - RingPiece ring; InternalChildren = new Drawable[] { circle = new CircularContainer @@ -45,18 +50,20 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components }; ring.Scale = new Vector2(spinner.Scale); - - spinner.PositionChanged += _ => updatePosition(); - spinner.StackHeightChanged += _ => updatePosition(); - spinner.ScaleChanged += _ => ring.Scale = new Vector2(spinner.Scale); - - updatePosition(); } [BackgroundDependencyLoader] private void load(OsuColour colours) { Colour = colours.Yellow; + + positionBindable.BindValueChanged(_ => updatePosition()); + stackHeightBindable.BindValueChanged(_ => updatePosition()); + scaleBindable.BindValueChanged(v => ring.Scale = new Vector2(v)); + + positionBindable.BindTo(spinner.PositionBindable); + stackHeightBindable.BindTo(spinner.StackHeightBindable); + scaleBindable.BindTo(spinner.ScaleBindable); } private void updatePosition() => Position = spinner.Position; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index e663989eeb..bf662adf1e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -2,6 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; @@ -21,6 +23,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly NumberPiece number; private readonly GlowPiece glow; + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable stackHeightBindable = new Bindable(); + private readonly IBindable scaleBindable = new Bindable(); + public DrawableHitCircle(HitCircle h) : base(h) { @@ -59,10 +65,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables //may not be so correct Size = circle.DrawSize; + } - HitObject.PositionChanged += _ => Position = HitObject.StackedPosition; - HitObject.StackHeightChanged += _ => Position = HitObject.StackedPosition; - HitObject.ScaleChanged += s => Scale = new Vector2(s); + [BackgroundDependencyLoader] + private void load() + { + positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); + stackHeightBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); + scaleBindable.BindValueChanged(v => Scale = new Vector2(v)); + + positionBindable.BindTo(HitObject.PositionBindable); + stackHeightBindable.BindTo(HitObject.StackHeightBindable); + scaleBindable.BindTo(HitObject.ScaleBindable); } public override Color4 AccentColour diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 514ae09064..63506a57a7 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; using osu.Game.Rulesets.Scoring; @@ -26,6 +27,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public readonly SnakingSliderBody Body; public readonly SliderBall Ball; + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable scaleBindable = new Bindable(); + private readonly IBindable controlPointsBindable = new Bindable(); + public DrawableSlider(Slider s) : base(s) { @@ -83,15 +88,26 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables components.Add(drawableRepeatPoint); AddNested(drawableRepeatPoint); } + } - HitObject.PositionChanged += _ => Position = HitObject.StackedPosition; - HitObject.ScaleChanged += _ => + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.SnakingInSliders, Body.SnakingIn); + config.BindWith(OsuSetting.SnakingOutSliders, Body.SnakingOut); + + positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); + scaleBindable.BindValueChanged(v => { Body.PathWidth = HitObject.Scale * 64; Ball.Scale = new Vector2(HitObject.Scale); - }; + }); - slider.ControlPointsChanged += _ => Body.Refresh(); + controlPointsBindable.BindValueChanged(_ => Body.Refresh()); + + positionBindable.BindTo(HitObject.PositionBindable); + scaleBindable.BindTo(HitObject.ScaleBindable); + controlPointsBindable.BindTo(slider.ControlPointsBindable); } public override Color4 AccentColour @@ -108,13 +124,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - config.BindWith(OsuSetting.SnakingInSliders, Body.SnakingIn); - config.BindWith(OsuSetting.SnakingOutSliders, Body.SnakingOut); - } - public bool Tracking; protected override void Update() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs index 6a836679a2..ab63c2b67e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs @@ -2,6 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Game.Rulesets.Objects.Types; using OpenTK; @@ -9,17 +11,25 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public class DrawableSliderHead : DrawableHitCircle { + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable controlPointsBindable = new Bindable(); + private readonly Slider slider; public DrawableSliderHead(Slider slider, HitCircle h) : base(h) { this.slider = slider; + } - h.PositionChanged += _ => updatePosition(); - slider.ControlPointsChanged += _ => updatePosition(); + [BackgroundDependencyLoader] + private void load() + { + positionBindable.BindValueChanged(_ => updatePosition()); + controlPointsBindable.BindValueChanged(_ => updatePosition()); - updatePosition(); + positionBindable.BindTo(HitObject.PositionBindable); + controlPointsBindable.BindTo(slider.ControlPointsBindable); } protected override void Update() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index cc88a6718b..c15f2e3704 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -1,8 +1,10 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; +using OpenTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -17,6 +19,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public bool Tracking { get; set; } + private readonly IBindable positionBindable = new Bindable(); + private readonly IBindable controlPointsBindable = new Bindable(); + public DrawableSliderTail(Slider slider, SliderTailCircle hitCircle) : base(hitCircle) { @@ -29,10 +34,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AlwaysPresent = true; - hitCircle.PositionChanged += _ => updatePosition(); - slider.ControlPointsChanged += _ => updatePosition(); + positionBindable.BindValueChanged(_ => updatePosition()); + controlPointsBindable.BindValueChanged(_ => updatePosition()); - updatePosition(); + positionBindable.BindTo(hitCircle.PositionBindable); + controlPointsBindable.BindTo(slider.ControlPointsBindable); } protected override void CheckForResult(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index f3846bd52f..56a85c3983 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -11,6 +11,7 @@ using OpenTK.Graphics; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Game.Screens.Ranking; using osu.Game.Rulesets.Scoring; @@ -36,6 +37,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Color4 baseColour = OsuColour.FromHex(@"002c3c"); private readonly Color4 fillColour = OsuColour.FromHex(@"005b7c"); + private readonly IBindable positionBindable = new Bindable(); + private Color4 normalColour; private Color4 completeColour; @@ -112,8 +115,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Alpha = 0 } }; + } - s.PositionChanged += _ => Position = s.Position; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + normalColour = baseColour; + + Background.AccentColour = normalColour; + + completeColour = colours.YellowLight.Opacity(0.75f); + + Disc.AccentColour = fillColour; + circle.Colour = colours.BlueDark; + glow.Colour = colours.BlueDark; + + positionBindable.BindValueChanged(v => Position = v); + positionBindable.BindTo(HitObject.PositionBindable); } public float Progress => MathHelper.Clamp(Disc.RotationAbsolute / 360 / Spinner.SpinsRequired, 0, 1); @@ -153,20 +171,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - normalColour = baseColour; - - Background.AccentColour = normalColour; - - completeColour = colours.YellowLight.Opacity(0.75f); - - Disc.AccentColour = fillColour; - circle.Colour = colours.BlueDark; - glow.Colour = colours.BlueDark; - } - protected override void Update() { Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false; diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 61d199a7dc..b7f9b2fa47 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; +using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using OpenTK; @@ -14,26 +14,15 @@ namespace osu.Game.Rulesets.Osu.Objects { public const double OBJECT_RADIUS = 64; - public event Action PositionChanged; - public event Action StackHeightChanged; - public event Action ScaleChanged; - public double TimePreempt = 600; public double TimeFadeIn = 400; - private Vector2 position; + public readonly Bindable PositionBindable = new Bindable(); public virtual Vector2 Position { - get => position; - set - { - if (position == value) - return; - position = value; - - PositionChanged?.Invoke(value); - } + get => PositionBindable; + set => PositionBindable.Value = value; } public float X => Position.X; @@ -45,38 +34,24 @@ namespace osu.Game.Rulesets.Osu.Objects public Vector2 StackedEndPosition => EndPosition + StackOffset; - private int stackHeight; + public readonly Bindable StackHeightBindable = new Bindable(); public int StackHeight { - get => stackHeight; - set - { - if (stackHeight == value) - return; - stackHeight = value; - - StackHeightChanged?.Invoke(value); - } + get => StackHeightBindable; + set => StackHeightBindable.Value = value; } public Vector2 StackOffset => new Vector2(StackHeight * Scale * -6.4f); public double Radius => OBJECT_RADIUS * Scale; - private float scale = 1; + public readonly Bindable ScaleBindable = new Bindable(1); public float Scale { - get => scale; - set - { - if (scale == value) - return; - scale = value; - - ScaleChanged?.Invoke(value); - } + get => ScaleBindable; + set => ScaleBindable.Value = value; } public virtual bool NewCombo { get; set; } diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index cff742ca29..133a2e57ab 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; using osu.Game.Rulesets.Objects; using System.Linq; +using osu.Framework.Configuration; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -22,8 +23,6 @@ namespace osu.Game.Rulesets.Osu.Objects /// private const float base_scoring_distance = 100; - public event Action ControlPointsChanged; - public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; @@ -54,17 +53,16 @@ namespace osu.Game.Rulesets.Osu.Objects public SliderPath Path { get; } = new SliderPath(); + public readonly Bindable ControlPointsBindable = new Bindable(Array.Empty()); + public Vector2[] ControlPoints { - get => Path.ControlPoints; + get => ControlPointsBindable; set { - if (Path.ControlPoints == value) - return; + ControlPointsBindable.Value = value; Path.ControlPoints = value; - ControlPointsChanged?.Invoke(value); - if (TailCircle != null) TailCircle.Position = EndPosition; } From 13279f707b871552b37d97b5fcba35e843c328dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 9 Nov 2018 14:19:50 +0900 Subject: [PATCH 04/12] Cleanups --- .../HitCircles/Components/HitCirclePiece.cs | 19 +++------- .../Edit/Blueprints/HitObjectPiece.cs | 36 +++++++++++++++++++ .../Edit/Blueprints/SliderPiece.cs | 32 +++++++++++++++++ .../Components/PathControlPointVisualiser.cs | 10 ++---- .../Sliders/Components/SliderBodyPiece.cs | 15 +++----- .../Spinners/Components/SpinnerPiece.cs | 18 +++------- 6 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Edit/Blueprints/HitObjectPiece.cs create mode 100644 osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs index 89d1b1fc46..3008be5e12 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs @@ -2,9 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; @@ -12,15 +10,12 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components { - public class HitCirclePiece : CompositeDrawable + public class HitCirclePiece : HitObjectPiece { - private readonly IBindable positionBindable = new Bindable(); - private readonly IBindable stackHeightBindable = new Bindable(); - private readonly IBindable scaleBindable = new Bindable(); - private readonly HitCircle hitCircle; public HitCirclePiece(HitCircle hitCircle) + : base(hitCircle) { this.hitCircle = hitCircle; Origin = Anchor.Centre; @@ -37,13 +32,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components { Colour = colours.Yellow; - positionBindable.BindValueChanged(_ => UpdatePosition()); - stackHeightBindable.BindValueChanged(_ => UpdatePosition()); - scaleBindable.BindValueChanged(v => Scale = new Vector2(v)); - - positionBindable.BindTo(hitCircle.PositionBindable); - stackHeightBindable.BindTo(hitCircle.StackHeightBindable); - scaleBindable.BindTo(hitCircle.ScaleBindable); + PositionBindable.BindValueChanged(_ => UpdatePosition(), true); + StackHeightBindable.BindValueChanged(_ => UpdatePosition()); + ScaleBindable.BindValueChanged(v => Scale = new Vector2(v), true); } protected virtual void UpdatePosition() => Position = hitCircle.StackedPosition; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitObjectPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitObjectPiece.cs new file mode 100644 index 0000000000..21ec46895b --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitObjectPiece.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Osu.Objects; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Edit.Blueprints +{ + /// + /// A piece of a blueprint which responds to changes in the state of a . + /// + public abstract class HitObjectPiece : CompositeDrawable + { + protected readonly IBindable PositionBindable = new Bindable(); + protected readonly IBindable StackHeightBindable = new Bindable(); + protected readonly IBindable ScaleBindable = new Bindable(); + + private readonly OsuHitObject hitObject; + + protected HitObjectPiece(OsuHitObject hitObject) + { + this.hitObject = hitObject; + } + + [BackgroundDependencyLoader] + private void load() + { + PositionBindable.BindTo(hitObject.PositionBindable); + StackHeightBindable.BindTo(hitObject.StackHeightBindable); + ScaleBindable.BindTo(hitObject.ScaleBindable); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs new file mode 100644 index 0000000000..587471d7dd --- /dev/null +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Game.Rulesets.Osu.Objects; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Edit.Blueprints +{ + /// + /// A piece of a blueprint which responds to changes in the state of a . + /// + public abstract class SliderPiece : HitObjectPiece + { + protected readonly IBindable ControlPointsBindable = new Bindable(); + + private readonly Slider slider; + + protected SliderPiece(Slider slider) + : base(slider) + { + this.slider = slider; + } + + [BackgroundDependencyLoader] + private void load() + { + ControlPointsBindable.BindTo(slider.ControlPointsBindable); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 2f3fe241e7..ffe32a9a72 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -2,23 +2,20 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Osu.Objects; -using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { - public class PathControlPointVisualiser : CompositeDrawable + public class PathControlPointVisualiser : SliderPiece { - private readonly IBindable controlPointsBindable = new Bindable(); - private readonly Slider slider; private readonly Container pieces; public PathControlPointVisualiser(Slider slider) + : base(slider) { this.slider = slider; @@ -28,8 +25,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components [BackgroundDependencyLoader] private void load() { - controlPointsBindable.BindValueChanged(_ => updatePathControlPoints()); - controlPointsBindable.BindTo(slider.ControlPointsBindable); + ControlPointsBindable.BindValueChanged(_ => updatePathControlPoints(), true); } private void updatePathControlPoints() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index 206e337ab7..bd55009374 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; @@ -13,15 +11,13 @@ using OpenTK.Graphics; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { - public class SliderBodyPiece : CompositeDrawable + public class SliderBodyPiece : SliderPiece { - private readonly IBindable positionBindable = new Bindable(); - private readonly IBindable scaleBindable = new Bindable(); - private readonly Slider slider; private readonly ManualSliderBody body; public SliderBodyPiece(Slider slider) + : base(slider) { this.slider = slider; @@ -37,11 +33,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { body.BorderColour = colours.Yellow; - positionBindable.BindValueChanged(_ => updatePosition()); - scaleBindable.BindValueChanged(v => body.PathWidth = v * 64); - - positionBindable.BindTo(slider.PositionBindable); - scaleBindable.BindTo(slider.ScaleBindable); + PositionBindable.BindValueChanged(_ => updatePosition(), true); + ScaleBindable.BindValueChanged(v => body.PathWidth = v * 64, true); } private void updatePosition() => Position = slider.StackedPosition; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs index d6104a5926..77d42133d2 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -13,17 +12,14 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components { - public class SpinnerPiece : CompositeDrawable + public class SpinnerPiece : HitObjectPiece { - private readonly IBindable positionBindable = new Bindable(); - private readonly IBindable stackHeightBindable = new Bindable(); - private readonly IBindable scaleBindable = new Bindable(); - private readonly Spinner spinner; private readonly CircularContainer circle; private readonly RingPiece ring; public SpinnerPiece(Spinner spinner) + : base(spinner) { this.spinner = spinner; @@ -57,13 +53,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components { Colour = colours.Yellow; - positionBindable.BindValueChanged(_ => updatePosition()); - stackHeightBindable.BindValueChanged(_ => updatePosition()); - scaleBindable.BindValueChanged(v => ring.Scale = new Vector2(v)); - - positionBindable.BindTo(spinner.PositionBindable); - stackHeightBindable.BindTo(spinner.StackHeightBindable); - scaleBindable.BindTo(spinner.ScaleBindable); + PositionBindable.BindValueChanged(_ => updatePosition(), true); + StackHeightBindable.BindValueChanged(_ => updatePosition()); + ScaleBindable.BindValueChanged(v => ring.Scale = new Vector2(v), true); } private void updatePosition() => Position = spinner.Position; From 023924396d0005e6acc560014d4c64363e645368 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sun, 11 Nov 2018 18:38:12 +0100 Subject: [PATCH 05/12] Move flashlight code from OsuModFlashlight to ModFlashlight and implement other modes and break time --- .../Mods/CatchModFlashlight.cs | 68 ++++++++- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 8 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- .../Mods/ManiaModFadeIn.cs | 3 +- .../Mods/ManiaModFlashlight.cs | 48 +++++- .../Mods/ManiaModHidden.cs | 3 +- .../Mods/OsuModFlashlight.cs | 98 +++++------- .../Difficulty/TaikoPerformanceCalculator.cs | 4 +- .../Mods/TaikoModFlashlight.cs | 83 +++++++++- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +- osu.Game/Rulesets/Mods/ModFlashlight.cs | 143 +++++++++++++++++- 11 files changed, 388 insertions(+), 80 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs index 21e09f991c..93e8257913 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs @@ -1,12 +1,78 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using JetBrains.Annotations; +using osu.Framework.Graphics; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch.Mods { - public class CatchModFlashlight : ModFlashlight + public class CatchModFlashlight : ModFlashlight { public override double ScoreMultiplier => 1.12; + + private const float default_flashlight_size = 350; + + public override Flashlight CreateFlashlight() => new CatchFlashlight(playfield); + + private CatchPlayfield playfield; + + public override void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + playfield = (CatchPlayfield)rulesetContainer.Playfield; + base.ApplyToRulesetContainer(rulesetContainer); + } + + private class CatchFlashlight : Flashlight + { + private readonly CatchPlayfield playfield; + + public CatchFlashlight(CatchPlayfield playfield) + { + this.playfield = playfield; + MousePosWrapper.CircularFlashlightSize = getSizeFor(0); + MousePosWrapper.Rectangular = false; + } + + protected override void Update() + { + base.Update(); + + MousePosWrapper.FlashlightPosition = (playfield.CatcherArea.MovableCatcher.ScreenSpaceDrawQuad.TopLeft + playfield.CatcherArea.MovableCatcher.ScreenSpaceDrawQuad.TopRight) / 2; + MousePosWrapper.FlashlightPositionChanged = true; + } + + [UsedImplicitly] + private float flashlightSize + { + set + { + if (MousePosWrapper.CircularFlashlightSize == value) return; + + MousePosWrapper.CircularFlashlightSize = value; + MousePosWrapper.CircularFlashlightSizeChanged = true; + } + + get => MousePosWrapper.CircularFlashlightSize; + } + + 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(int newCombo) + { + this.TransformTo(nameof(flashlightSize), getSizeFor(newCombo), FLASHLIGHT_FADE_DURATION); + } + } } } diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 925e7aaac9..b121d6814b 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.UI { public const float BASE_WIDTH = 512; - private readonly CatcherArea catcherArea; + internal readonly CatcherArea CatcherArea; protected override bool UserScrollSpeedAdjustment => false; @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.UI { RelativeSizeAxes = Axes.Both, }, - catcherArea = new CatcherArea(difficulty) + CatcherArea = new CatcherArea(difficulty) { GetVisualRepresentation = getVisualRepresentation, ExplodingFruitTarget = explodingFruitContainer, @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.UI VisibleTimeRange.Value = BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); } - public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj); + public bool CheckIfWeCanCatch(CatchHitObject obj) => CatcherArea.AttemptCatch(obj); public override void Add(DrawableHitObject h) { @@ -72,6 +72,6 @@ namespace osu.Game.Rulesets.Catch.UI } private void onNewResult(DrawableHitObject judgedObject, JudgementResult result) - => catcherArea.OnResult((DrawableCatchHitObject)judgedObject, result); + => CatcherArea.OnResult((DrawableCatchHitObject)judgedObject, result); } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 06453ac32d..8661a3c162 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.UI { public const float CATCHER_SIZE = 100; - protected readonly Catcher MovableCatcher; + protected internal readonly Catcher MovableCatcher; public Func> GetVisualRepresentation; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs index 08815ede09..73942cbb53 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs @@ -3,6 +3,7 @@ using System; using osu.Game.Graphics; +using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Mania.Mods @@ -16,6 +17,6 @@ namespace osu.Game.Rulesets.Mania.Mods public override string Description => @"Keys appear out of nowhere!"; public override double ScoreMultiplier => 1; public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; + public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs index d7a1bc4fbe..be45bb7296 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs @@ -2,13 +2,59 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Graphics; +using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; +using OpenTK; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModFlashlight : ModFlashlight + public class ManiaModFlashlight : ModFlashlight { public override double ScoreMultiplier => 1; public override Type[] IncompatibleMods => new[] { typeof(ModHidden) }; + + private const float default_flashlight_size = 180; + + public override Flashlight CreateFlashlight() => new ManiaFlashlight(); + + private class ManiaFlashlight : Flashlight + { + public ManiaFlashlight() + { + MousePosWrapper.Rectangular = true; + MousePosWrapper.RectangularFlashlightSize = new Vector2(0, default_flashlight_size); + } + + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + if ((invalidation & Invalidation.DrawSize) > 0) + { + Schedule(() => + { + MousePosWrapper.RectangularFlashlightSize.X = DrawWidth; + MousePosWrapper.RectangularFlashlightSizeChanged = true; + + MousePosWrapper.FlashlightPosition = ScreenSpaceDrawQuad.Centre; + MousePosWrapper.FlashlightPositionChanged = true; + }); + } + + return base.Invalidate(invalidation, source, shallPropagate); + } + + protected override void OnComboChange(int newCombo) + { + } + + protected override void LoadComplete() + { + MousePosWrapper.RectangularFlashlightSize.X = DrawWidth; + MousePosWrapper.RectangularFlashlightSizeChanged = true; + + MousePosWrapper.FlashlightPosition = ScreenSpaceDrawQuad.Centre; + MousePosWrapper.FlashlightPositionChanged = true; + } + } } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 2ef68a35fa..9bc2502a8f 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Mania.Mods @@ -10,6 +11,6 @@ namespace osu.Game.Rulesets.Mania.Mods { public override string Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; - public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; + public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs index c6b6d67ce6..a5f803f726 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -1,95 +1,65 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using osu.Framework.Allocation; +using JetBrains.Annotations; using osu.Framework.Graphics; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; -using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.UI; -using OpenTK; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlashlight : ModFlashlight, IApplicableToRulesetContainer + public class OsuModFlashlight : ModFlashlight { public override double ScoreMultiplier => 1.12; - public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + private const float default_flashlight_size = 180; + + public override Flashlight CreateFlashlight() => new OsuFlashlight(); + + private class OsuFlashlight : Flashlight, IRequireHighFrequencyMousePosition { - rulesetContainer.KeyBindingInputManager.Add(new Flashlight + public OsuFlashlight() { - RelativeSizeAxes = Axes.Both, - }); - } - - private class Flashlight : Drawable, IRequireHighFrequencyMousePosition - { - private Shader shader; - private readonly MousePositionWrapper mousePosWrapper = new MousePositionWrapper - { - FlashlightSize = 300f - }; - - protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); - - protected override void ApplyDrawNode(DrawNode node) - { - base.ApplyDrawNode(node); - - var flashNode = (FlashlightDrawNode)node; - - flashNode.Shader = shader; - flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; - flashNode.MousePosWrapper = mousePosWrapper; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaderManager) - { - shader = shaderManager.Load(VertexShaderDescriptor.POSITION, "Flashlight"); + MousePosWrapper.CircularFlashlightSize = getSizeFor(0); + MousePosWrapper.Rectangular = false; } protected override bool OnMouseMove(MouseMoveEvent e) { - mousePosWrapper.MousePosition = e.ScreenSpaceMousePosition; + MousePosWrapper.FlashlightPosition = e.ScreenSpaceMousePosition; + MousePosWrapper.FlashlightPositionChanged = true; return base.OnMouseMove(e); } - } - private class MousePositionWrapper - { - public Vector2 MousePosition; - public float FlashlightSize; - public bool FlashlightUniformUpdated; - } - - private class FlashlightDrawNode : DrawNode - { - public Shader Shader; - public Quad ScreenSpaceDrawQuad; - public MousePositionWrapper MousePosWrapper; - - public override void Draw(Action vertexAction) + [UsedImplicitly] + private float flashlightSize { - base.Draw(vertexAction); + set + { + if (MousePosWrapper.CircularFlashlightSize == value) return; - Shader.Bind(); - // ReSharper disable once AssignmentInConditionalExpression - if(MousePosWrapper.FlashlightUniformUpdated = !MousePosWrapper.FlashlightUniformUpdated) - Shader.GetUniform("flashlightSize").UpdateValue(ref MousePosWrapper.FlashlightSize); + MousePosWrapper.CircularFlashlightSize = value; + MousePosWrapper.CircularFlashlightSizeChanged = true; + } - Shader.GetUniform("mousePos").UpdateValue(ref MousePosWrapper.MousePosition); + get => MousePosWrapper.CircularFlashlightSize; + } - Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); + 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; + } - Shader.Unbind(); + protected override void OnComboChange(int newCombo) + { + this.TransformTo(nameof(flashlightSize), getSizeFor(newCombo), FLASHLIGHT_FADE_DURATION); } } } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index f530b6725c..86dd37b476 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -8,6 +8,8 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Taiko.Mods; +using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Difficulty { @@ -82,7 +84,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (mods.Any(m => m is ModHidden)) strainValue *= 1.025; - if (mods.Any(m => m is ModFlashlight)) + if (mods.Any(m => m is ModFlashlight)) // Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps. strainValue *= 1.05 * lengthBonus; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index 49f7786f59..8e14f24bb3 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -1,12 +1,93 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using JetBrains.Annotations; +using osu.Framework.Graphics; +using osu.Framework.Input; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.UI; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko.Mods { - public class TaikoModFlashlight : ModFlashlight + public class TaikoModFlashlight : ModFlashlight { public override double ScoreMultiplier => 1.12; + + private const float default_flashlight_size = 250; + + public override Flashlight CreateFlashlight() => new TaikoFlashlight(playfield); + + private TaikoPlayfield playfield; + + public override void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + playfield = (TaikoPlayfield)rulesetContainer.Playfield; + base.ApplyToRulesetContainer(rulesetContainer); + } + + private class TaikoFlashlight : Flashlight + { + private readonly TaikoPlayfield taikoPlayfield; + + public TaikoFlashlight(TaikoPlayfield taikoPlayfield) + { + this.taikoPlayfield = taikoPlayfield; + MousePosWrapper.CircularFlashlightSize = getSizeFor(0); + MousePosWrapper.Rectangular = false; + } + + [UsedImplicitly] + private float flashlightSize + { + set + { + if (MousePosWrapper.CircularFlashlightSize == value) return; + + MousePosWrapper.CircularFlashlightSize = value; + MousePosWrapper.CircularFlashlightSizeChanged = true; + } + + get => MousePosWrapper.CircularFlashlightSize; + } + + 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(int newCombo) + { + this.TransformTo(nameof(flashlightSize), getSizeFor(newCombo), FLASHLIGHT_FADE_DURATION); + } + + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + if ((invalidation & Invalidation.DrawSize) > 0) + { + Schedule(() => + { + MousePosWrapper.FlashlightPosition = taikoPlayfield.HitExplosionContainer.ScreenSpaceDrawQuad.Centre; + MousePosWrapper.FlashlightPositionChanged = true; + }); + } + + return base.Invalidate(invalidation, source, shallPropagate); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + MousePosWrapper.FlashlightPosition = taikoPlayfield.HitExplosionContainer.ScreenSpaceDrawQuad.Centre; + MousePosWrapper.FlashlightPositionChanged = true; + } + } } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 40ed659bd6..5e1593638c 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Taiko.UI protected override SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Overlapping; - private readonly Container hitExplosionContainer; + internal readonly Container HitExplosionContainer; private readonly Container kiaiExplosionContainer; private readonly JudgementContainer judgementContainer; @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.UI Masking = true, Children = new Drawable[] { - hitExplosionContainer = new Container + HitExplosionContainer = new Container { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, @@ -243,7 +243,7 @@ namespace osu.Game.Rulesets.Taiko.UI { case TaikoStrongJudgement _: if (result.IsHit) - hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).MainObject)?.VisualiseSecondHit(); + HitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).MainObject)?.VisualiseSecondHit(); break; default: judgementContainer.Add(new DrawableTaikoJudgement(result, judgedObject) @@ -259,7 +259,7 @@ namespace osu.Game.Rulesets.Taiko.UI bool isRim = judgedObject.HitObject is RimHit; - hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); + HitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); if (judgedObject.HitObject.Kiai) kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 223263195c..a99f4e81fb 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -1,11 +1,27 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Game.Beatmaps.Timing; using osu.Game.Graphics; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Mods { - public abstract class ModFlashlight : Mod + public abstract class ModFlashlight : Mod, IApplicableToRulesetContainer, IApplicableToScoreProcessor + where T : HitObject { public override string Name => "Flashlight"; public override string ShortenedName => "FL"; @@ -13,5 +29,130 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Restricted view area."; public override bool Ranked => true; + + public const double FLASHLIGHT_FADE_DURATION = 800; + protected readonly BindableInt Combo = new BindableInt(); + + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + Combo.BindTo(scoreProcessor.Combo); + } + + public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + var flashlight = CreateFlashlight(); + flashlight.Combo = Combo; + flashlight.RelativeSizeAxes = Axes.Both; + flashlight.Colour = Color4.Black; + rulesetContainer.KeyBindingInputManager.Add(flashlight); + + flashlight.Breaks = rulesetContainer.Beatmap.Breaks; + } + + public abstract Flashlight CreateFlashlight(); + + public abstract class Flashlight : Drawable + { + internal BindableInt Combo; + private Shader shader; + protected readonly FlashlightUniformWrapper MousePosWrapper = new FlashlightUniformWrapper(); + + protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); + + public override bool RemoveCompletedTransforms => false; + + public List Breaks; + + protected override void ApplyDrawNode(DrawNode node) + { + base.ApplyDrawNode(node); + + var flashNode = (FlashlightDrawNode)node; + + flashNode.Shader = shader; + flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; + flashNode.MousePosWrapper = MousePosWrapper; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaderManager) + { + shader = shaderManager.Load("PositionAndColour", "Flashlight"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Combo.ValueChanged += OnComboChange; + + this.FadeInFromZero(FLASHLIGHT_FADE_DURATION); + + foreach (var breakPeriod in Breaks) + { + this.Delay(breakPeriod.StartTime + FLASHLIGHT_FADE_DURATION).FadeOutFromOne(FLASHLIGHT_FADE_DURATION); + this.Delay(breakPeriod.EndTime - FLASHLIGHT_FADE_DURATION).FadeInFromZero(FLASHLIGHT_FADE_DURATION); + } + } + + protected abstract void OnComboChange(int newCombo); + } + + public class FlashlightUniformWrapper + { + public bool Rectangular; + public bool RectangularChanged = true; + + public Vector2 FlashlightPosition; + public bool FlashlightPositionChanged = true; + + public float CircularFlashlightSize; + public bool CircularFlashlightSizeChanged = true; + + public Vector2 RectangularFlashlightSize; + public bool RectangularFlashlightSizeChanged = true; + } + + private class FlashlightDrawNode : DrawNode + { + public Shader Shader; + public Quad ScreenSpaceDrawQuad; + public FlashlightUniformWrapper MousePosWrapper; + + public override void Draw(Action vertexAction) + { + base.Draw(vertexAction); + + Shader.Bind(); + + if (MousePosWrapper.RectangularChanged) + { + Shader.GetUniform("rectangular").UpdateValue(ref MousePosWrapper.Rectangular); + MousePosWrapper.RectangularChanged = false; + } + + if (MousePosWrapper.FlashlightPositionChanged) + { + Shader.GetUniform("flashlightPos").UpdateValue(ref MousePosWrapper.FlashlightPosition); + MousePosWrapper.FlashlightPositionChanged = false; + } + + if (MousePosWrapper.CircularFlashlightSizeChanged) + { + Shader.GetUniform("circularFlashlightSize").UpdateValue(ref MousePosWrapper.CircularFlashlightSize); + MousePosWrapper.CircularFlashlightSizeChanged = false; + } + + if (MousePosWrapper.RectangularFlashlightSizeChanged) + { + Shader.GetUniform("rectangularFlashlightSize").UpdateValue(ref MousePosWrapper.RectangularFlashlightSize); + MousePosWrapper.RectangularFlashlightSizeChanged = false; + } + + Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); + + Shader.Unbind(); + } + } } } From 050af88be96dbd9d5a4e94b072ca20855e71f861 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 14 Nov 2018 14:29:22 +0900 Subject: [PATCH 06/12] Fix post-merge issues --- .../Edit/Blueprints/SliderPiece.cs | 6 +++--- .../Components/PathControlPointVisualiser.cs | 2 +- .../Sliders/Components/SliderCirclePiece.cs | 8 ++++---- .../Objects/Drawables/DrawableSlider.cs | 9 +++++---- .../Objects/Drawables/DrawableSliderHead.cs | 11 ++++++----- .../Objects/Drawables/DrawableSliderTail.cs | 11 ++++++----- osu.Game.Rulesets.Osu/Objects/Slider.cs | 15 ++++----------- osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs | 10 ++++++++++ 8 files changed, 39 insertions(+), 33 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs index 587471d7dd..ef7254d9c9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/SliderPiece.cs @@ -3,8 +3,8 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; -using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints { @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints /// public abstract class SliderPiece : HitObjectPiece { - protected readonly IBindable ControlPointsBindable = new Bindable(); + protected readonly IBindable PathBindable = new Bindable(); private readonly Slider slider; @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints [BackgroundDependencyLoader] private void load() { - ControlPointsBindable.BindTo(slider.ControlPointsBindable); + PathBindable.BindTo(slider.PathBindable); } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index a317965e57..0089c2dddd 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components [BackgroundDependencyLoader] private void load() { - ControlPointsBindable.BindValueChanged(_ => updatePathControlPoints(), true); + PathBindable.BindValueChanged(_ => updatePathControlPoints(), true); } private void updatePathControlPoints() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs index 17e823603f..205ac6bea3 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderCirclePiece.cs @@ -3,15 +3,15 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Objects; -using OpenTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class SliderCirclePiece : HitCirclePiece { - private readonly IBindable controlPointsBindable = new Bindable(); + private readonly IBindable pathBindable = new Bindable(); private readonly Slider slider; private readonly SliderPosition position; @@ -26,8 +26,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components [BackgroundDependencyLoader] private void load() { - controlPointsBindable.BindValueChanged(_ => UpdatePosition()); - controlPointsBindable.BindTo(slider.ControlPointsBindable); + pathBindable.BindTo(slider.PathBindable); + pathBindable.BindValueChanged(_ => UpdatePosition(), true); } protected override void UpdatePosition() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 63506a57a7..d304374614 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -11,6 +11,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using OpenTK.Graphics; @@ -29,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly IBindable positionBindable = new Bindable(); private readonly IBindable scaleBindable = new Bindable(); - private readonly IBindable controlPointsBindable = new Bindable(); + private readonly IBindable pathBindable = new Bindable(); public DrawableSlider(Slider s) : base(s) @@ -103,11 +104,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Ball.Scale = new Vector2(HitObject.Scale); }); - controlPointsBindable.BindValueChanged(_ => Body.Refresh()); - positionBindable.BindTo(HitObject.PositionBindable); scaleBindable.BindTo(HitObject.ScaleBindable); - controlPointsBindable.BindTo(slider.ControlPointsBindable); + pathBindable.BindTo(slider.PathBindable); + + pathBindable.BindValueChanged(_ => Body.Refresh()); } public override Color4 AccentColour diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs index ab63c2b67e..d3c006e74d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; @@ -12,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public class DrawableSliderHead : DrawableHitCircle { private readonly IBindable positionBindable = new Bindable(); - private readonly IBindable controlPointsBindable = new Bindable(); + private readonly IBindable pathBindable = new Bindable(); private readonly Slider slider; @@ -25,11 +26,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables [BackgroundDependencyLoader] private void load() { - positionBindable.BindValueChanged(_ => updatePosition()); - controlPointsBindable.BindValueChanged(_ => updatePosition()); - positionBindable.BindTo(HitObject.PositionBindable); - controlPointsBindable.BindTo(slider.ControlPointsBindable); + pathBindable.BindTo(slider.PathBindable); + + positionBindable.BindValueChanged(_ => updatePosition()); + pathBindable.BindValueChanged(_ => updatePosition(), true); } protected override void Update() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index c15f2e3704..eb7a5964c5 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -3,6 +3,7 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using OpenTK; @@ -20,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public bool Tracking { get; set; } private readonly IBindable positionBindable = new Bindable(); - private readonly IBindable controlPointsBindable = new Bindable(); + private readonly IBindable pathBindable = new Bindable(); public DrawableSliderTail(Slider slider, SliderTailCircle hitCircle) : base(hitCircle) @@ -34,11 +35,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AlwaysPresent = true; - positionBindable.BindValueChanged(_ => updatePosition()); - controlPointsBindable.BindValueChanged(_ => updatePosition()); - positionBindable.BindTo(hitCircle.PositionBindable); - controlPointsBindable.BindTo(slider.ControlPointsBindable); + pathBindable.BindTo(slider.PathBindable); + + positionBindable.BindValueChanged(_ => updatePosition()); + pathBindable.BindValueChanged(_ => updatePosition(), true); } protected override void CheckForResult(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 026a44e74b..6471c8c572 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -51,19 +51,12 @@ namespace osu.Game.Rulesets.Osu.Objects } } - private SliderPath path; + public readonly Bindable PathBindable = new Bindable(); public SliderPath Path { - get => path; - set - { - path = value; - - PathChanged?.Invoke(value); - if (TailCircle != null) - TailCircle.Position = EndPosition; - } + get => PathBindable.Value; + set => PathBindable.Value = value; } public double Distance => Path.Distance; @@ -162,7 +155,7 @@ namespace osu.Game.Rulesets.Osu.Objects ComboIndex = ComboIndex, }; - TailCircle = new SliderTailCircle + TailCircle = new SliderTailCircle(this) { StartTime = EndTime, Position = EndPosition, diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs index b567bd8423..74a7a8d446 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs @@ -1,13 +1,23 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects { public class SliderTailCircle : SliderCircle { + private readonly IBindable pathBindable = new Bindable(); + + public SliderTailCircle(Slider slider) + { + pathBindable.BindTo(slider.PathBindable); + pathBindable.BindValueChanged(_ => Position = slider.EndPosition); + } + public override Judgement CreateJudgement() => new OsuSliderTailJudgement(); } } From 7d2958b7b0f35cce6655dc7248909c7d9278d687 Mon Sep 17 00:00:00 2001 From: jorolf Date: Thu, 15 Nov 2018 00:33:13 +0100 Subject: [PATCH 07/12] split shader, remove unnecessary clutter and fix some bugs --- .../Mods/CatchModFlashlight.cs | 26 ++----- .../Mods/ManiaModFlashlight.cs | 17 ++--- .../Mods/OsuModFlashlight.cs | 26 ++----- .../Mods/TaikoModFlashlight.cs | 30 ++------ osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 11 +-- osu.Game/Rulesets/Mods/ModFlashlight.cs | 74 +++++++++---------- 6 files changed, 70 insertions(+), 114 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs index 93e8257913..8645730d09 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; +using OpenTK; namespace osu.Game.Rulesets.Catch.Mods { @@ -33,30 +33,16 @@ namespace osu.Game.Rulesets.Catch.Mods public CatchFlashlight(CatchPlayfield playfield) { this.playfield = playfield; - MousePosWrapper.CircularFlashlightSize = getSizeFor(0); - MousePosWrapper.Rectangular = false; + FlashlightSize = new Vector2(0, getSizeFor(0)); } protected override void Update() { base.Update(); - MousePosWrapper.FlashlightPosition = (playfield.CatcherArea.MovableCatcher.ScreenSpaceDrawQuad.TopLeft + playfield.CatcherArea.MovableCatcher.ScreenSpaceDrawQuad.TopRight) / 2; - MousePosWrapper.FlashlightPositionChanged = true; - } + var catcher = playfield.CatcherArea.MovableCatcher; - [UsedImplicitly] - private float flashlightSize - { - set - { - if (MousePosWrapper.CircularFlashlightSize == value) return; - - MousePosWrapper.CircularFlashlightSize = value; - MousePosWrapper.CircularFlashlightSizeChanged = true; - } - - get => MousePosWrapper.CircularFlashlightSize; + FlashlightPosition = catcher.ToSpaceOfOtherDrawable(catcher.Position, this); } private float getSizeFor(int combo) @@ -71,8 +57,10 @@ namespace osu.Game.Rulesets.Catch.Mods protected override void OnComboChange(int newCombo) { - this.TransformTo(nameof(flashlightSize), getSizeFor(newCombo), FLASHLIGHT_FADE_DURATION); + this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(newCombo)), FLASHLIGHT_FADE_DURATION); } + + protected override string FragmentShader => "CircularFlashlight"; } } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs index be45bb7296..32ac668f69 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs @@ -22,8 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods { public ManiaFlashlight() { - MousePosWrapper.Rectangular = true; - MousePosWrapper.RectangularFlashlightSize = new Vector2(0, default_flashlight_size); + FlashlightSize = new Vector2(0, default_flashlight_size); } public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) @@ -32,11 +31,9 @@ namespace osu.Game.Rulesets.Mania.Mods { Schedule(() => { - MousePosWrapper.RectangularFlashlightSize.X = DrawWidth; - MousePosWrapper.RectangularFlashlightSizeChanged = true; + FlashlightSize = new Vector2(DrawWidth, FlashlightSize.Y); - MousePosWrapper.FlashlightPosition = ScreenSpaceDrawQuad.Centre; - MousePosWrapper.FlashlightPositionChanged = true; + FlashlightPosition = DrawPosition + DrawSize / 2; }); } @@ -47,13 +44,13 @@ namespace osu.Game.Rulesets.Mania.Mods { } + protected override string FragmentShader => "RectangularFlashlight"; + protected override void LoadComplete() { - MousePosWrapper.RectangularFlashlightSize.X = DrawWidth; - MousePosWrapper.RectangularFlashlightSizeChanged = true; + FlashlightSize = new Vector2(DrawWidth, FlashlightSize.Y); - MousePosWrapper.FlashlightPosition = ScreenSpaceDrawQuad.Centre; - MousePosWrapper.FlashlightPositionChanged = true; + FlashlightPosition = DrawPosition + DrawSize / 2; } } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs index a5f803f726..f425b3c53d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; +using OpenTK; namespace osu.Game.Rulesets.Osu.Mods { @@ -22,31 +22,15 @@ namespace osu.Game.Rulesets.Osu.Mods { public OsuFlashlight() { - MousePosWrapper.CircularFlashlightSize = getSizeFor(0); - MousePosWrapper.Rectangular = false; + FlashlightSize = new Vector2(0, getSizeFor(0)); } protected override bool OnMouseMove(MouseMoveEvent e) { - MousePosWrapper.FlashlightPosition = e.ScreenSpaceMousePosition; - MousePosWrapper.FlashlightPositionChanged = true; + FlashlightPosition = e.MousePosition; return base.OnMouseMove(e); } - [UsedImplicitly] - private float flashlightSize - { - set - { - if (MousePosWrapper.CircularFlashlightSize == value) return; - - MousePosWrapper.CircularFlashlightSize = value; - MousePosWrapper.CircularFlashlightSizeChanged = true; - } - - get => MousePosWrapper.CircularFlashlightSize; - } - private float getSizeFor(int combo) { if (combo > 200) @@ -59,8 +43,10 @@ namespace osu.Game.Rulesets.Osu.Mods protected override void OnComboChange(int newCombo) { - this.TransformTo(nameof(flashlightSize), getSizeFor(newCombo), FLASHLIGHT_FADE_DURATION); + this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(newCombo)), FLASHLIGHT_FADE_DURATION); } + + protected override string FragmentShader => "CircularFlashlight"; } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index 8e14f24bb3..a58d55f904 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -1,13 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using JetBrains.Annotations; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; +using OpenTK; namespace osu.Game.Rulesets.Taiko.Mods { @@ -34,22 +33,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public TaikoFlashlight(TaikoPlayfield taikoPlayfield) { this.taikoPlayfield = taikoPlayfield; - MousePosWrapper.CircularFlashlightSize = getSizeFor(0); - MousePosWrapper.Rectangular = false; - } - - [UsedImplicitly] - private float flashlightSize - { - set - { - if (MousePosWrapper.CircularFlashlightSize == value) return; - - MousePosWrapper.CircularFlashlightSize = value; - MousePosWrapper.CircularFlashlightSizeChanged = true; - } - - get => MousePosWrapper.CircularFlashlightSize; + FlashlightSize = new Vector2(0, getSizeFor(0)); } private float getSizeFor(int combo) @@ -64,17 +48,18 @@ namespace osu.Game.Rulesets.Taiko.Mods protected override void OnComboChange(int newCombo) { - this.TransformTo(nameof(flashlightSize), getSizeFor(newCombo), FLASHLIGHT_FADE_DURATION); + this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(newCombo)), FLASHLIGHT_FADE_DURATION); } + protected override string FragmentShader => "CircularFlashlight"; + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { if ((invalidation & Invalidation.DrawSize) > 0) { Schedule(() => { - MousePosWrapper.FlashlightPosition = taikoPlayfield.HitExplosionContainer.ScreenSpaceDrawQuad.Centre; - MousePosWrapper.FlashlightPositionChanged = true; + FlashlightPosition = taikoPlayfield.HitTarget.ToSpaceOfOtherDrawable(taikoPlayfield.HitTarget.OriginPosition, this); }); } @@ -85,8 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Mods { base.LoadComplete(); - MousePosWrapper.FlashlightPosition = taikoPlayfield.HitExplosionContainer.ScreenSpaceDrawQuad.Centre; - MousePosWrapper.FlashlightPositionChanged = true; + FlashlightPosition = taikoPlayfield.HitTarget.ToSpaceOfOtherDrawable(taikoPlayfield.HitTarget.OriginPosition, this); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 5e1593638c..a1a2b1b88e 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -43,9 +43,10 @@ namespace osu.Game.Rulesets.Taiko.UI protected override SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Overlapping; - internal readonly Container HitExplosionContainer; + private readonly Container hitExplosionContainer; private readonly Container kiaiExplosionContainer; private readonly JudgementContainer judgementContainer; + internal readonly HitTarget HitTarget; private readonly Container topLevelHitContainer; @@ -103,13 +104,13 @@ namespace osu.Game.Rulesets.Taiko.UI Masking = true, Children = new Drawable[] { - HitExplosionContainer = new Container + hitExplosionContainer = new Container { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, Blending = BlendingMode.Additive, }, - new HitTarget + HitTarget = new HitTarget { Anchor = Anchor.CentreLeft, Origin = Anchor.Centre, @@ -243,7 +244,7 @@ namespace osu.Game.Rulesets.Taiko.UI { case TaikoStrongJudgement _: if (result.IsHit) - HitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).MainObject)?.VisualiseSecondHit(); + hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).MainObject)?.VisualiseSecondHit(); break; default: judgementContainer.Add(new DrawableTaikoJudgement(result, judgedObject) @@ -259,7 +260,7 @@ namespace osu.Game.Rulesets.Taiko.UI bool isRim = judgedObject.HitObject is RimHit; - HitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); + hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); if (judgedObject.HitObject.Kiai) kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index a99f4e81fb..2063f5cf88 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -55,7 +55,6 @@ namespace osu.Game.Rulesets.Mods { internal BindableInt Combo; private Shader shader; - protected readonly FlashlightUniformWrapper MousePosWrapper = new FlashlightUniformWrapper(); protected override DrawNode CreateDrawNode() => new FlashlightDrawNode(); @@ -71,13 +70,14 @@ namespace osu.Game.Rulesets.Mods flashNode.Shader = shader; flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; - flashNode.MousePosWrapper = MousePosWrapper; + flashNode.MousePosWrapper.FlashlightPosition = Vector2Extensions.Transform(FlashlightPosition, DrawInfo.Matrix); + flashNode.MousePosWrapper.FlashlightSize = Vector2Extensions.Transform(FlashlightSize, DrawInfo.Matrix); } [BackgroundDependencyLoader] private void load(ShaderManager shaderManager) { - shader = shaderManager.Load("PositionAndColour", "Flashlight"); + shader = shaderManager.Load("PositionAndColour", FragmentShader); } protected override void LoadComplete() @@ -90,27 +90,48 @@ namespace osu.Game.Rulesets.Mods foreach (var breakPeriod in Breaks) { + if (breakPeriod.Duration < FLASHLIGHT_FADE_DURATION * 2) continue; + this.Delay(breakPeriod.StartTime + FLASHLIGHT_FADE_DURATION).FadeOutFromOne(FLASHLIGHT_FADE_DURATION); this.Delay(breakPeriod.EndTime - FLASHLIGHT_FADE_DURATION).FadeInFromZero(FLASHLIGHT_FADE_DURATION); } } protected abstract void OnComboChange(int newCombo); + + protected abstract string FragmentShader { get; } + + private Vector2 flashlightPosition; + protected Vector2 FlashlightPosition + { + get => flashlightPosition; + set + { + if (flashlightPosition == value) return; + + flashlightPosition = value; + Invalidate(Invalidation.DrawNode); + } + } + + private Vector2 flashlightSize; + protected Vector2 FlashlightSize + { + get => flashlightSize; + set + { + if (flashlightSize == value) return; + + flashlightSize = value; + Invalidate(Invalidation.DrawNode); + } + } } - public class FlashlightUniformWrapper + public struct FlashlightUniformWrapper { - public bool Rectangular; - public bool RectangularChanged = true; - public Vector2 FlashlightPosition; - public bool FlashlightPositionChanged = true; - - public float CircularFlashlightSize; - public bool CircularFlashlightSizeChanged = true; - - public Vector2 RectangularFlashlightSize; - public bool RectangularFlashlightSizeChanged = true; + public Vector2 FlashlightSize; } private class FlashlightDrawNode : DrawNode @@ -125,29 +146,8 @@ namespace osu.Game.Rulesets.Mods Shader.Bind(); - if (MousePosWrapper.RectangularChanged) - { - Shader.GetUniform("rectangular").UpdateValue(ref MousePosWrapper.Rectangular); - MousePosWrapper.RectangularChanged = false; - } - - if (MousePosWrapper.FlashlightPositionChanged) - { - Shader.GetUniform("flashlightPos").UpdateValue(ref MousePosWrapper.FlashlightPosition); - MousePosWrapper.FlashlightPositionChanged = false; - } - - if (MousePosWrapper.CircularFlashlightSizeChanged) - { - Shader.GetUniform("circularFlashlightSize").UpdateValue(ref MousePosWrapper.CircularFlashlightSize); - MousePosWrapper.CircularFlashlightSizeChanged = false; - } - - if (MousePosWrapper.RectangularFlashlightSizeChanged) - { - Shader.GetUniform("rectangularFlashlightSize").UpdateValue(ref MousePosWrapper.RectangularFlashlightSize); - MousePosWrapper.RectangularFlashlightSizeChanged = false; - } + Shader.GetUniform("flashlightPos").UpdateValue(ref MousePosWrapper.FlashlightPosition); + Shader.GetUniform("flashlightSize").UpdateValue(ref MousePosWrapper.FlashlightSize); Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); From f0f7b15edcd1a7715ec7aeb7baf14fa737543cd3 Mon Sep 17 00:00:00 2001 From: jorolf Date: Thu, 15 Nov 2018 00:45:27 +0100 Subject: [PATCH 08/12] remove unused using --- osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 86dd37b476..734d5d0ad7 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -8,7 +8,6 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Difficulty From 80bd98bb9d1e0d1824cca8862caec6203272a17b Mon Sep 17 00:00:00 2001 From: jorolf Date: Thu, 15 Nov 2018 17:38:38 +0100 Subject: [PATCH 09/12] apply suggestions --- .../Mods/CatchModFlashlight.cs | 4 +-- .../Mods/ManiaModFlashlight.cs | 30 +++++++++++-------- .../Mods/TaikoModFlashlight.cs | 17 ++++++----- osu.Game/Rulesets/Mods/ModFlashlight.cs | 17 ++++------- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs index 8645730d09..6592b8b313 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs @@ -40,9 +40,9 @@ namespace osu.Game.Rulesets.Catch.Mods { base.Update(); - var catcher = playfield.CatcherArea.MovableCatcher; + var catcherArea = playfield.CatcherArea; - FlashlightPosition = catcher.ToSpaceOfOtherDrawable(catcher.Position, this); + FlashlightPosition = catcherArea.ToSpaceOfOtherDrawable(catcherArea.MovableCatcher.DrawPosition, this); } private float getSizeFor(int combo) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs index 32ac668f69..e0e395ce55 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; @@ -20,6 +21,8 @@ namespace osu.Game.Rulesets.Mania.Mods private class ManiaFlashlight : Flashlight { + private readonly Cached flashlightProperties = new Cached(); + public ManiaFlashlight() { FlashlightSize = new Vector2(0, default_flashlight_size); @@ -29,29 +32,30 @@ namespace osu.Game.Rulesets.Mania.Mods { if ((invalidation & Invalidation.DrawSize) > 0) { - Schedule(() => - { - FlashlightSize = new Vector2(DrawWidth, FlashlightSize.Y); - - FlashlightPosition = DrawPosition + DrawSize / 2; - }); + flashlightProperties.Invalidate(); } return base.Invalidate(invalidation, source, shallPropagate); } + protected override void Update() + { + base.Update(); + + if (!flashlightProperties.IsValid) + { + FlashlightSize = new Vector2(DrawWidth, FlashlightSize.Y); + + FlashlightPosition = DrawPosition + DrawSize / 2; + flashlightProperties.Validate(); + } + } + protected override void OnComboChange(int newCombo) { } protected override string FragmentShader => "RectangularFlashlight"; - - protected override void LoadComplete() - { - FlashlightSize = new Vector2(DrawWidth, FlashlightSize.Y); - - FlashlightPosition = DrawPosition + DrawSize / 2; - } } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index a58d55f904..5e865d7727 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; @@ -28,6 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Mods private class TaikoFlashlight : Flashlight { + private readonly Cached flashlightProperties = new Cached(); private readonly TaikoPlayfield taikoPlayfield; public TaikoFlashlight(TaikoPlayfield taikoPlayfield) @@ -57,20 +59,21 @@ namespace osu.Game.Rulesets.Taiko.Mods { if ((invalidation & Invalidation.DrawSize) > 0) { - Schedule(() => - { - FlashlightPosition = taikoPlayfield.HitTarget.ToSpaceOfOtherDrawable(taikoPlayfield.HitTarget.OriginPosition, this); - }); + flashlightProperties.Invalidate(); } return base.Invalidate(invalidation, source, shallPropagate); } - protected override void LoadComplete() + protected override void Update() { - base.LoadComplete(); + base.Update(); - FlashlightPosition = taikoPlayfield.HitTarget.ToSpaceOfOtherDrawable(taikoPlayfield.HitTarget.OriginPosition, this); + if (!flashlightProperties.IsValid) + { + FlashlightPosition = taikoPlayfield.HitTarget.ToSpaceOfOtherDrawable(taikoPlayfield.HitTarget.OriginPosition, this); + flashlightProperties.Validate(); + } } } } diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 2063f5cf88..5e5353bfdd 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -70,8 +70,8 @@ namespace osu.Game.Rulesets.Mods flashNode.Shader = shader; flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad; - flashNode.MousePosWrapper.FlashlightPosition = Vector2Extensions.Transform(FlashlightPosition, DrawInfo.Matrix); - flashNode.MousePosWrapper.FlashlightSize = Vector2Extensions.Transform(FlashlightSize, DrawInfo.Matrix); + flashNode.FlashlightPosition = Vector2Extensions.Transform(FlashlightPosition, DrawInfo.Matrix); + flashNode.FlashlightSize = Vector2Extensions.Transform(FlashlightSize, DrawInfo.Matrix); } [BackgroundDependencyLoader] @@ -128,17 +128,12 @@ namespace osu.Game.Rulesets.Mods } } - public struct FlashlightUniformWrapper - { - public Vector2 FlashlightPosition; - public Vector2 FlashlightSize; - } - private class FlashlightDrawNode : DrawNode { public Shader Shader; public Quad ScreenSpaceDrawQuad; - public FlashlightUniformWrapper MousePosWrapper; + public Vector2 FlashlightPosition; + public Vector2 FlashlightSize; public override void Draw(Action vertexAction) { @@ -146,8 +141,8 @@ namespace osu.Game.Rulesets.Mods Shader.Bind(); - Shader.GetUniform("flashlightPos").UpdateValue(ref MousePosWrapper.FlashlightPosition); - Shader.GetUniform("flashlightSize").UpdateValue(ref MousePosWrapper.FlashlightSize); + Shader.GetUniform("flashlightPos").UpdateValue(ref FlashlightPosition); + Shader.GetUniform("flashlightSize").UpdateValue(ref FlashlightSize); Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction); From 37b19f78ae476e54f67ae7631a82be9716cc7001 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 15 Nov 2018 23:37:21 +0300 Subject: [PATCH 10/12] Set AccentColour in concrete counters --- osu.Game/Graphics/UserInterface/PercentageCounter.cs | 4 ++++ osu.Game/Graphics/UserInterface/ScoreCounter.cs | 4 ++++ osu.Game/Graphics/UserInterface/SimpleComboCounter.cs | 4 ++++ osu.Game/Screens/Play/HUDOverlay.cs | 5 ----- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index ef3fc156e7..b1514cb8c8 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; namespace osu.Game.Graphics.UserInterface { @@ -25,6 +26,9 @@ namespace osu.Game.Graphics.UserInterface Current.Value = DisplayedCount = 1.0f; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) => AccentColour = colours.BlueLighter; + protected override string FormatCount(double count) { return $@"{count:P2}"; diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index df26f81629..8bf30c32c6 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Graphics; namespace osu.Game.Graphics.UserInterface @@ -31,6 +32,9 @@ namespace osu.Game.Graphics.UserInterface LeadingZeroes = leading; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) => AccentColour = colours.BlueLighter; + protected override double GetProportionalDuration(double currentValue, double newValue) { return currentValue > newValue ? currentValue - newValue : newValue - currentValue; diff --git a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs index cf55240e71..ddc48c9be7 100644 --- a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs +++ b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; namespace osu.Game.Graphics.UserInterface { @@ -17,6 +18,9 @@ namespace osu.Game.Graphics.UserInterface Current.Value = DisplayedCount = 0; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) => AccentColour = colours.BlueLighter; + protected override string FormatCount(int count) { return $@"{count}x"; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 93d92d062d..daf5b72ebd 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -105,11 +105,6 @@ namespace osu.Game.Screens.Play }); } - // todo: the stuff below should probably not be in this base implementation, but in each individual class. - ComboCounter.AccentColour = colours.BlueLighter; - AccuracyCounter.AccentColour = colours.BlueLighter; - ScoreCounter.AccentColour = colours.BlueLighter; - var shd = HealthDisplay as StandardHealthDisplay; if (shd != null) { From 92b1c56aed4de75b24b02fc809a4a288b17c7271 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 16 Nov 2018 18:31:37 +0900 Subject: [PATCH 11/12] Update osu-resources --- osu-resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-resources b/osu-resources index 651e598b01..694cb03f19 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 651e598b016b43e31ab1c1b29d5b30c92361b8d9 +Subproject commit 694cb03f19c93106ed0f2593f3e506e835fb652a From ecf8a89f26fadffd2c47eaae4e2c02334f6571cf Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 16 Nov 2018 19:30:58 +0300 Subject: [PATCH 12/12] Set AccentColour and GlowColour in StandardHealthDisplay --- osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs | 8 ++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 10 +--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs b/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs index b551b1f7a6..850ab9f641 100644 --- a/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/StandardHealthDisplay.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -92,6 +93,13 @@ namespace osu.Game.Screens.Play.HUD }; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AccentColour = colours.BlueLighter; + GlowColour = colours.BlueDarker; + } + public void Flash(JudgementResult result) { if (result.Type == HitResult.Miss) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index daf5b72ebd..beed14b293 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -9,7 +9,6 @@ using osu.Framework.Input.Events; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -89,7 +88,7 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader(true)] - private void load(OsuConfigManager config, NotificationOverlay notificationOverlay, OsuColour colours) + private void load(OsuConfigManager config, NotificationOverlay notificationOverlay) { showHud = config.GetBindable(OsuSetting.ShowInterface); showHud.ValueChanged += hudVisibility => content.FadeTo(hudVisibility ? 1 : 0, duration); @@ -104,13 +103,6 @@ namespace osu.Game.Screens.Play Text = @"The score overlay is currently disabled. You can toggle this by pressing Shift+Tab." }); } - - var shd = HealthDisplay as StandardHealthDisplay; - if (shd != null) - { - shd.AccentColour = colours.BlueLighter; - shd.GlowColour = colours.BlueDarker; - } } protected override void LoadComplete()