Merge branch 'master' into fix-mask-disposal

This commit is contained in:
Dean Herbert 2018-11-18 21:18:00 +09:00 committed by GitHub
commit dd21daa635
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 422 additions and 19 deletions

@ -1 +1 @@
Subproject commit 651e598b016b43e31ab1c1b29d5b30c92361b8d9
Subproject commit 694cb03f19c93106ed0f2593f3e506e835fb652a

View File

@ -1,12 +1,66 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
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
{
public class CatchModFlashlight : ModFlashlight
public class CatchModFlashlight : ModFlashlight<CatchHitObject>
{
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<CatchHitObject> rulesetContainer)
{
playfield = (CatchPlayfield)rulesetContainer.Playfield;
base.ApplyToRulesetContainer(rulesetContainer);
}
private class CatchFlashlight : Flashlight
{
private readonly CatchPlayfield playfield;
public CatchFlashlight(CatchPlayfield playfield)
{
this.playfield = playfield;
FlashlightSize = new Vector2(0, getSizeFor(0));
}
protected override void Update()
{
base.Update();
var catcherArea = playfield.CatcherArea;
FlashlightPosition = catcherArea.ToSpaceOfOtherDrawable(catcherArea.MovableCatcher.DrawPosition, this);
}
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), new Vector2(0, getSizeFor(newCombo)), FLASHLIGHT_FADE_DURATION);
}
protected override string FragmentShader => "CircularFlashlight";
}
}
}

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.UI
{
public const float BASE_WIDTH = 512;
private readonly CatcherArea catcherArea;
internal readonly CatcherArea CatcherArea;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
{
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Catch.UI
{
RelativeSizeAxes = Axes.Both,
},
catcherArea = new CatcherArea(difficulty)
CatcherArea = new CatcherArea(difficulty)
{
GetVisualRepresentation = getVisualRepresentation,
ExplodingFruitTarget = explodingFruitContainer,
@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.UI
};
}
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);
public bool CheckIfWeCanCatch(CatchHitObject obj) => CatcherArea.AttemptCatch(obj);
public override void Add(DrawableHitObject h)
{
@ -63,6 +63,6 @@ namespace osu.Game.Rulesets.Catch.UI
}
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result)
=> catcherArea.OnResult((DrawableCatchHitObject)judgedObject, result);
=> CatcherArea.OnResult((DrawableCatchHitObject)judgedObject, result);
}
}

View File

@ -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<CatchHitObject, DrawableHitObject<CatchHitObject>> GetVisualRepresentation;

View File

@ -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<ManiaHitObject>) };
}
}

View File

@ -2,13 +2,60 @@
// 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;
using OpenTK;
namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModFlashlight : ModFlashlight
public class ManiaModFlashlight : ModFlashlight<ManiaHitObject>
{
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
{
private readonly Cached flashlightProperties = new Cached();
public ManiaFlashlight()
{
FlashlightSize = 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)
{
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";
}
}
}

View File

@ -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<ManiaHitObject>) };
}
}

View File

@ -1,12 +1,52 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
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
{
public class OsuModFlashlight : ModFlashlight
public class OsuModFlashlight : ModFlashlight<OsuHitObject>
{
public override double ScoreMultiplier => 1.12;
private const float default_flashlight_size = 180;
public override Flashlight CreateFlashlight() => new OsuFlashlight();
private class OsuFlashlight : Flashlight, IRequireHighFrequencyMousePosition
{
public OsuFlashlight()
{
FlashlightSize = new Vector2(0, getSizeFor(0));
}
protected override bool OnMouseMove(MouseMoveEvent e)
{
FlashlightPosition = e.MousePosition;
return base.OnMouseMove(e);
}
private float getSizeFor(int combo)
{
if (combo > 200)
return default_flashlight_size * 0.8f;
else if (combo > 100)
return default_flashlight_size * 0.9f;
else
return default_flashlight_size;
}
protected override void OnComboChange(int newCombo)
{
this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(newCombo)), FLASHLIGHT_FADE_DURATION);
}
protected override string FragmentShader => "CircularFlashlight";
}
}
}

View File

@ -8,6 +8,7 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
namespace osu.Game.Rulesets.Taiko.Difficulty
{
@ -82,7 +83,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<TaikoHitObject>))
// Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps.
strainValue *= 1.05 * lengthBonus;

View File

@ -1,12 +1,80 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// 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;
using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Rulesets.UI;
using OpenTK;
namespace osu.Game.Rulesets.Taiko.Mods
{
public class TaikoModFlashlight : ModFlashlight
public class TaikoModFlashlight : ModFlashlight<TaikoHitObject>
{
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<TaikoHitObject> rulesetContainer)
{
playfield = (TaikoPlayfield)rulesetContainer.Playfield;
base.ApplyToRulesetContainer(rulesetContainer);
}
private class TaikoFlashlight : Flashlight
{
private readonly Cached flashlightProperties = new Cached();
private readonly TaikoPlayfield taikoPlayfield;
public TaikoFlashlight(TaikoPlayfield taikoPlayfield)
{
this.taikoPlayfield = taikoPlayfield;
FlashlightSize = new Vector2(0, getSizeFor(0));
}
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), 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)
{
flashlightProperties.Invalidate();
}
return base.Invalidate(invalidation, source, shallPropagate);
}
protected override void Update()
{
base.Update();
if (!flashlightProperties.IsValid)
{
FlashlightPosition = taikoPlayfield.HitTarget.ToSpaceOfOtherDrawable(taikoPlayfield.HitTarget.OriginPosition, this);
flashlightProperties.Validate();
}
}
}
}
}

View File

@ -41,6 +41,7 @@ namespace osu.Game.Rulesets.Taiko.UI
private readonly Container<HitExplosion> hitExplosionContainer;
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
private readonly JudgementContainer<DrawableTaikoJudgement> judgementContainer;
internal readonly HitTarget HitTarget;
private readonly Container topLevelHitContainer;
@ -102,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.UI
FillMode = FillMode.Fit,
Blending = BlendingMode.Additive,
},
new HitTarget
HitTarget = new HitTarget
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,

View File

@ -0,0 +1,41 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
namespace osu.Game.Input
{
public class IdleTracker : Component, IKeyBindingHandler<PlatformAction>
{
private double lastInteractionTime;
public double IdleTime => Clock.CurrentTime - lastInteractionTime;
private bool updateLastInteractionTime()
{
lastInteractionTime = Clock.CurrentTime;
return false;
}
public bool OnPressed(PlatformAction action) => updateLastInteractionTime();
public bool OnReleased(PlatformAction action) => updateLastInteractionTime();
protected override bool Handle(UIEvent e)
{
switch (e)
{
case KeyDownEvent _:
case KeyUpEvent _:
case MouseDownEvent _:
case MouseUpEvent _:
case MouseMoveEvent _:
return updateLastInteractionTime();
default:
return base.Handle(e);
}
}
}
}

View File

@ -26,6 +26,7 @@ using osu.Framework.Platform;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Input;
using osu.Game.Rulesets.Scoring;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
@ -86,6 +87,8 @@ namespace osu.Game
public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight;
private IdleTracker idleTracker;
public readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>();
private OsuScreen screenStack;
@ -311,6 +314,7 @@ namespace osu.Game
},
mainContent = new Container { RelativeSizeAxes = Axes.Both },
overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
idleTracker = new IdleTracker { RelativeSizeAxes = Axes.Both }
});
loadComponentSingleFile(screenStack = new Loader(), d =>
@ -372,6 +376,7 @@ namespace osu.Game
Depth = -6,
}, overlayContent.Add);
dependencies.Cache(idleTracker);
dependencies.Cache(settings);
dependencies.Cache(onscreenDisplay);
dependencies.Cache(social);

View File

@ -8,6 +8,10 @@ namespace osu.Game.Overlays.Settings
{
public class SettingsTextBox : SettingsItem<string>
{
protected override Drawable CreateControl() => new OsuTextBox();
protected override Drawable CreateControl() => new OsuTextBox
{
Margin = new MarginPadding { Top = 5 },
RelativeSizeAxes = Axes.X,
};
}
}

View File

@ -1,11 +1,27 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// 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<T> : Mod, IApplicableToRulesetContainer<T>, IApplicableToScoreProcessor
where T : HitObject
{
public override string Name => "Flashlight";
public override string ShortenedName => "FL";
@ -13,5 +29,125 @@ 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<T> 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 override DrawNode CreateDrawNode() => new FlashlightDrawNode();
public override bool RemoveCompletedTransforms => false;
public List<BreakPeriod> Breaks;
protected override void ApplyDrawNode(DrawNode node)
{
base.ApplyDrawNode(node);
var flashNode = (FlashlightDrawNode)node;
flashNode.Shader = shader;
flashNode.ScreenSpaceDrawQuad = ScreenSpaceDrawQuad;
flashNode.FlashlightPosition = Vector2Extensions.Transform(FlashlightPosition, DrawInfo.Matrix);
flashNode.FlashlightSize = Vector2Extensions.Transform(FlashlightSize, DrawInfo.Matrix);
}
[BackgroundDependencyLoader]
private void load(ShaderManager shaderManager)
{
shader = shaderManager.Load("PositionAndColour", FragmentShader);
}
protected override void LoadComplete()
{
base.LoadComplete();
Combo.ValueChanged += OnComboChange;
this.FadeInFromZero(FLASHLIGHT_FADE_DURATION);
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);
}
}
}
private class FlashlightDrawNode : DrawNode
{
public Shader Shader;
public Quad ScreenSpaceDrawQuad;
public Vector2 FlashlightPosition;
public Vector2 FlashlightSize;
public override void Draw(Action<TexturedVertex2D> vertexAction)
{
base.Draw(vertexAction);
Shader.Bind();
Shader.GetUniform<Vector2>("flashlightPos").UpdateValue(ref FlashlightPosition);
Shader.GetUniform<Vector2>("flashlightSize").UpdateValue(ref FlashlightSize);
Texture.WhitePixel.DrawQuad(ScreenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction);
Shader.Unbind();
}
}
}
}

View File

@ -14,6 +14,7 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Logging;
using osu.Framework.Threading;
using osu.Game.Graphics;
using osu.Game.Input;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using OpenTK;
@ -64,6 +65,8 @@ namespace osu.Game.Screens.Menu
private SampleChannel sampleBack;
private IdleTracker idleTracker;
public ButtonSystem()
{
RelativeSizeAxes = Axes.Both;
@ -102,9 +105,10 @@ namespace osu.Game.Screens.Menu
private OsuGame game;
[BackgroundDependencyLoader(true)]
private void load(AudioManager audio, OsuGame game)
private void load(AudioManager audio, OsuGame game, IdleTracker idleTracker)
{
this.game = game;
this.idleTracker = idleTracker;
sampleBack = audio.Sample.Get(@"Menu/button-back-select");
}
@ -266,8 +270,8 @@ namespace osu.Game.Screens.Menu
protected override void Update()
{
//if (OsuGame.IdleTime > 6000 && State != MenuState.Exit)
// State = MenuState.Initial;
if (idleTracker?.IdleTime > 6000 && State != ButtonSystemState.Exit)
State = ButtonSystemState.Initial;
base.Update();