mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 09:32:55 +08:00
Merge branch 'master' into update-taiko-hitsounds
This commit is contained in:
commit
c8ccd3cfbf
@ -1 +1 @@
|
||||
Subproject commit 2610a3133721b0bc4af852342aa2a179d0e66497
|
||||
Subproject commit 90bf49a2df3dbad5994d922df63e4891c622dbc3
|
13
osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs
Normal file
13
osu.Game.Rulesets.Osu/Judgements/OsuSliderTailJudgement.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Judgements
|
||||
{
|
||||
public class OsuSliderTailJudgement : OsuJudgement
|
||||
{
|
||||
public override bool AffectsCombo => false;
|
||||
protected override int NumericResultFor(HitResult result) => 0;
|
||||
}
|
||||
}
|
@ -18,14 +18,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
public class DrawableSlider : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
|
||||
{
|
||||
private readonly Slider slider;
|
||||
|
||||
public readonly DrawableHitCircle InitialCircle;
|
||||
|
||||
private readonly List<Drawable> components = new List<Drawable>();
|
||||
|
||||
private readonly Container<DrawableSliderTick> ticks;
|
||||
private readonly Container<DrawableRepeatPoint> repeatPoints;
|
||||
|
||||
public readonly DrawableHitCircle HeadCircle;
|
||||
public readonly SliderBody Body;
|
||||
public readonly SliderBall Ball;
|
||||
|
||||
@ -34,6 +29,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
slider = s;
|
||||
|
||||
DrawableSliderTail tail;
|
||||
Container<DrawableSliderTick> ticks;
|
||||
Container<DrawableRepeatPoint> repeatPoints;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Body = new SliderBody(s)
|
||||
@ -51,27 +50,17 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
AlwaysPresent = true,
|
||||
Alpha = 0
|
||||
},
|
||||
InitialCircle = new DrawableHitCircle(new HitCircle
|
||||
{
|
||||
StartTime = s.StartTime,
|
||||
Position = s.StackedPosition,
|
||||
IndexInCurrentCombo = s.IndexInCurrentCombo,
|
||||
Scale = s.Scale,
|
||||
ComboColour = s.ComboColour,
|
||||
Samples = s.Samples,
|
||||
SampleControlPoint = s.SampleControlPoint,
|
||||
TimePreempt = s.TimePreempt,
|
||||
TimeFadein = s.TimeFadein,
|
||||
HitWindow300 = s.HitWindow300,
|
||||
HitWindow100 = s.HitWindow100,
|
||||
HitWindow50 = s.HitWindow50
|
||||
})
|
||||
HeadCircle = new DrawableHitCircle(s.HeadCircle),
|
||||
tail = new DrawableSliderTail(s.TailCircle)
|
||||
};
|
||||
|
||||
components.Add(Body);
|
||||
components.Add(Ball);
|
||||
|
||||
AddNested(InitialCircle);
|
||||
AddNested(HeadCircle);
|
||||
|
||||
AddNested(tail);
|
||||
components.Add(tail);
|
||||
|
||||
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
|
||||
{
|
||||
@ -87,6 +76,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
};
|
||||
|
||||
ticks.Add(drawableTick);
|
||||
components.Add(drawableTick);
|
||||
AddNested(drawableTick);
|
||||
}
|
||||
|
||||
@ -121,27 +111,25 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
currentSpan = span;
|
||||
|
||||
//todo: we probably want to reconsider this before adding scoring, but it looks and feels nice.
|
||||
if (!InitialCircle.Judgements.Any(j => j.IsHit))
|
||||
InitialCircle.Position = slider.Curve.PositionAt(progress);
|
||||
if (!HeadCircle.IsHit)
|
||||
HeadCircle.Position = slider.Curve.PositionAt(progress);
|
||||
|
||||
foreach (var c in components.OfType<ISliderProgress>()) c.UpdateProgress(progress, span);
|
||||
foreach (var c in components.OfType<ITrackSnaking>()) c.UpdateSnakingPosition(slider.Curve.PositionAt(Body.SnakedStart ?? 0), slider.Curve.PositionAt(Body.SnakedEnd ?? 0));
|
||||
foreach (var t in ticks.Children) t.Tracking = Ball.Tracking;
|
||||
foreach (var t in components.OfType<IRequireTracking>()) t.Tracking = Ball.Tracking;
|
||||
}
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (!userTriggered && Time.Current >= slider.EndTime)
|
||||
{
|
||||
var judgementsCount = ticks.Children.Count + repeatPoints.Children.Count + 1;
|
||||
var judgementsHit = ticks.Children.Count(t => t.Judgements.Any(j => j.IsHit)) + repeatPoints.Children.Count(t => t.Judgements.Any(j => j.IsHit));
|
||||
if (InitialCircle.Judgements.Any(j => j.IsHit))
|
||||
judgementsHit++;
|
||||
var judgementsCount = NestedHitObjects.Count;
|
||||
var judgementsHit = NestedHitObjects.Count(h => h.IsHit);
|
||||
|
||||
var hitFraction = (double)judgementsHit / judgementsCount;
|
||||
if (hitFraction == 1 && InitialCircle.Judgements.Any(j => j.Result == HitResult.Great))
|
||||
if (hitFraction == 1 && HeadCircle.Judgements.Any(j => j.Result == HitResult.Great))
|
||||
AddJudgement(new OsuJudgement { Result = HitResult.Great });
|
||||
else if (hitFraction >= 0.5 && InitialCircle.Judgements.Any(j => j.Result >= HitResult.Good))
|
||||
else if (hitFraction >= 0.5 && HeadCircle.Judgements.Any(j => j.Result >= HitResult.Good))
|
||||
AddJudgement(new OsuJudgement { Result = HitResult.Good });
|
||||
else if (hitFraction > 0)
|
||||
AddJudgement(new OsuJudgement { Result = HitResult.Meh });
|
||||
@ -173,7 +161,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
}
|
||||
}
|
||||
|
||||
public Drawable ProxiedLayer => InitialCircle.ApproachCircle;
|
||||
public Drawable ProxiedLayer => HeadCircle.ApproachCircle;
|
||||
|
||||
public override Vector2 SelectionPoint => ToScreenSpace(Body.Position);
|
||||
public override Quad SelectionQuad => Body.PathDrawQuad;
|
||||
|
@ -0,0 +1,32 @@
|
||||
// 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.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// The judgement text is provided by the <see cref="DrawableSlider"/>.
|
||||
/// </summary>
|
||||
public override bool DisplayJudgement => false;
|
||||
|
||||
public bool Tracking { get; set; }
|
||||
|
||||
public DrawableSliderTail(HitCircle hitCircle)
|
||||
: base(hitCircle)
|
||||
{
|
||||
AlwaysPresent = true;
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (!userTriggered && timeOffset >= 0)
|
||||
AddJudgement(new OsuSliderTailJudgement { Result = Tracking ? HitResult.Great : HitResult.Miss });
|
||||
}
|
||||
}
|
||||
}
|
@ -12,14 +12,14 @@ using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
public class DrawableSliderTick : DrawableOsuHitObject
|
||||
public class DrawableSliderTick : DrawableOsuHitObject, IRequireTracking
|
||||
{
|
||||
private readonly SliderTick sliderTick;
|
||||
|
||||
public double FadeInTime;
|
||||
public double FadeOutTime;
|
||||
|
||||
public bool Tracking;
|
||||
public bool Tracking { get; set; }
|
||||
|
||||
public override bool DisplayJudgement => false;
|
||||
|
||||
|
13
osu.Game.Rulesets.Osu/Objects/Drawables/IRequireTracking.cs
Normal file
13
osu.Game.Rulesets.Osu/Objects/Drawables/IRequireTracking.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
public interface IRequireTracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the <see cref="DrawableSlider"/> is currently being tracked by the user.
|
||||
/// </summary>
|
||||
bool Tracking { get; set; }
|
||||
}
|
||||
}
|
@ -80,6 +80,9 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
public double Velocity;
|
||||
public double TickDistance;
|
||||
|
||||
public HitCircle HeadCircle;
|
||||
public HitCircle TailCircle;
|
||||
|
||||
protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||
@ -97,10 +100,37 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
{
|
||||
base.CreateNestedHitObjects();
|
||||
|
||||
createSliderEnds();
|
||||
createTicks();
|
||||
createRepeatPoints();
|
||||
}
|
||||
|
||||
private void createSliderEnds()
|
||||
{
|
||||
HeadCircle = new HitCircle
|
||||
{
|
||||
StartTime = StartTime,
|
||||
Position = StackedPosition,
|
||||
IndexInCurrentCombo = IndexInCurrentCombo,
|
||||
ComboColour = ComboColour,
|
||||
Samples = Samples,
|
||||
SampleControlPoint = SampleControlPoint
|
||||
};
|
||||
|
||||
TailCircle = new HitCircle
|
||||
{
|
||||
StartTime = EndTime,
|
||||
Position = StackedEndPosition,
|
||||
IndexInCurrentCombo = IndexInCurrentCombo,
|
||||
ComboColour = ComboColour,
|
||||
Samples = Samples,
|
||||
SampleControlPoint = SampleControlPoint
|
||||
};
|
||||
|
||||
AddNested(HeadCircle);
|
||||
AddNested(TailCircle);
|
||||
}
|
||||
|
||||
private void createTicks()
|
||||
{
|
||||
if (TickDistance == 0) return;
|
||||
|
@ -16,6 +16,9 @@ using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using System.Linq;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
@ -142,7 +145,34 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
|
||||
mod.ApplyToDrawableHitObjects(new[] { drawable });
|
||||
|
||||
drawable.OnJudgement += onJudgement;
|
||||
|
||||
Add(drawable);
|
||||
}
|
||||
|
||||
private float judgementOffsetDirection = 1;
|
||||
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||
{
|
||||
var osuObject = judgedObject as DrawableOsuHitObject;
|
||||
if (osuObject == null)
|
||||
return;
|
||||
|
||||
OsuSpriteText text;
|
||||
Add(text = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = judgement.IsHit ? "Hit!" : "Miss!",
|
||||
Colour = judgement.IsHit ? Color4.Green : Color4.Red,
|
||||
TextSize = 30,
|
||||
Position = osuObject.HitObject.StackedEndPosition + judgementOffsetDirection * new Vector2(0, 45)
|
||||
});
|
||||
|
||||
text.Delay(150)
|
||||
.Then().FadeOut(200)
|
||||
.Then().Expire();
|
||||
|
||||
judgementOffsetDirection *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
<Compile Include="Edit\OsuEditPlayfield.cs" />
|
||||
<Compile Include="Edit\OsuEditRulesetContainer.cs" />
|
||||
<Compile Include="Edit\OsuHitObjectComposer.cs" />
|
||||
<Compile Include="Judgements\OsuSliderTailJudgement.cs" />
|
||||
<Compile Include="Mods\OsuModAutopilot.cs" />
|
||||
<Compile Include="Mods\OsuModAutoplay.cs" />
|
||||
<Compile Include="Mods\OsuModDaycore.cs" />
|
||||
@ -75,6 +76,8 @@
|
||||
<Compile Include="Objects\Drawables\Connections\FollowPointRenderer.cs" />
|
||||
<Compile Include="Judgements\OsuJudgement.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableRepeatPoint.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableSliderTail.cs" />
|
||||
<Compile Include="Objects\Drawables\IRequireTracking.cs" />
|
||||
<Compile Include="Objects\Drawables\ITrackSnaking.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\ApproachCircle.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\SpinnerBackground.cs" />
|
||||
|
@ -35,8 +35,8 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
bool hitButton = true;
|
||||
|
||||
Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None));
|
||||
Frames.Add(new ReplayFrame(Beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(-100000, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(Beatmap.HitObjects[0].StartTime - 1000, ReplayButtonState.None));
|
||||
|
||||
for (int i = 0; i < Beatmap.HitObjects.Count; i++)
|
||||
{
|
||||
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
break;
|
||||
}
|
||||
|
||||
Frames.Add(new ReplayFrame(j, null, null, button));
|
||||
Frames.Add(new TaikoReplayFrame(j, button));
|
||||
d = (d + 1) % 4;
|
||||
if (++count == req)
|
||||
break;
|
||||
@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
foreach (var tick in drumRoll.NestedHitObjects.OfType<DrumRollTick>())
|
||||
{
|
||||
Frames.Add(new ReplayFrame(tick.StartTime, null, null, hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2));
|
||||
Frames.Add(new TaikoReplayFrame(tick.StartTime, hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2));
|
||||
hitButton = !hitButton;
|
||||
}
|
||||
}
|
||||
@ -107,18 +107,18 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
|
||||
}
|
||||
|
||||
Frames.Add(new ReplayFrame(h.StartTime, null, null, button));
|
||||
Frames.Add(new TaikoReplayFrame(h.StartTime, button));
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException("Unknown hit object type.");
|
||||
|
||||
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY, ReplayButtonState.None));
|
||||
|
||||
if (i < Beatmap.HitObjects.Count - 1)
|
||||
{
|
||||
double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000;
|
||||
if (waitTime > endTime)
|
||||
Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(waitTime, ReplayButtonState.None));
|
||||
}
|
||||
|
||||
hitButton = !hitButton;
|
||||
|
17
osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs
Normal file
17
osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs
Normal file
@ -0,0 +1,17 @@
|
||||
// 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.Game.Rulesets.Replays;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
public class TaikoReplayFrame : ReplayFrame
|
||||
{
|
||||
public override bool IsImportant => MouseLeft || MouseRight;
|
||||
|
||||
public TaikoReplayFrame(double time, ReplayButtonState buttons)
|
||||
: base(time, null, null, buttons)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -95,6 +95,7 @@
|
||||
<Compile Include="Replays\TaikoAutoGenerator.cs" />
|
||||
<Compile Include="Objects\TaikoHitObject.cs" />
|
||||
<Compile Include="Objects\TaikoHitObjectDifficulty.cs" />
|
||||
<Compile Include="Replays\TaikoReplayFrame.cs" />
|
||||
<Compile Include="TaikoDifficultyCalculator.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Scoring\TaikoScoreProcessor.cs" />
|
||||
|
@ -8,6 +8,8 @@ using OpenTK;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Edit.Layers.Selection;
|
||||
using osu.Game.Rulesets.Osu.Edit;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
@ -35,9 +37,9 @@ namespace osu.Game.Tests.Visual
|
||||
new SelectionLayer(playfield)
|
||||
};
|
||||
|
||||
playfield.Add(new DrawableHitCircle(new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f }));
|
||||
playfield.Add(new DrawableHitCircle(new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f }));
|
||||
playfield.Add(new DrawableSlider(new Slider
|
||||
var hitCircle1 = new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f };
|
||||
var hitCircle2 = new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f };
|
||||
var slider = new Slider
|
||||
{
|
||||
ControlPoints = new List<Vector2>
|
||||
{
|
||||
@ -48,8 +50,16 @@ namespace osu.Game.Tests.Visual
|
||||
Position = new Vector2(128, 256),
|
||||
Velocity = 1,
|
||||
TickDistance = 100,
|
||||
Scale = 0.5f
|
||||
}));
|
||||
Scale = 0.5f,
|
||||
};
|
||||
|
||||
hitCircle1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
hitCircle2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
|
||||
playfield.Add(new DrawableHitCircle(hitCircle1));
|
||||
playfield.Add(new DrawableHitCircle(hitCircle2));
|
||||
playfield.Add(new DrawableSlider(slider));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public class IconButton : OsuClickableContainer
|
||||
{
|
||||
private const float button_size = 30;
|
||||
public const float BUTTON_SIZE = 30;
|
||||
|
||||
private Color4? flashColour;
|
||||
/// <summary>
|
||||
@ -106,7 +106,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
Origin = Anchor.Centre,
|
||||
Anchor = Anchor.Centre,
|
||||
Size = new Vector2(button_size),
|
||||
Size = new Vector2(BUTTON_SIZE),
|
||||
CornerRadius = 5,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Threading;
|
||||
using OpenTK;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Input.Bindings;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface.Volume
|
||||
@ -14,6 +15,7 @@ namespace osu.Game.Graphics.UserInterface.Volume
|
||||
public class VolumeControl : OverlayContainer
|
||||
{
|
||||
private readonly VolumeMeter volumeMeterMaster;
|
||||
private readonly IconButton muteIcon;
|
||||
|
||||
protected override bool BlockPassThroughMouse => false;
|
||||
|
||||
@ -34,6 +36,17 @@ namespace osu.Game.Graphics.UserInterface.Volume
|
||||
Spacing = new Vector2(15, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(IconButton.BUTTON_SIZE),
|
||||
Child = muteIcon = new IconButton
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_volume_up,
|
||||
Action = () => Adjust(GlobalAction.ToggleMute),
|
||||
}
|
||||
},
|
||||
volumeMeterMaster = new VolumeMeter("Master"),
|
||||
volumeMeterEffect = new VolumeMeter("Effects"),
|
||||
volumeMeterMusic = new VolumeMeter("Music")
|
||||
@ -46,18 +59,10 @@ namespace osu.Game.Graphics.UserInterface.Volume
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
volumeMeterMaster.Bindable.ValueChanged += volumeChanged;
|
||||
volumeMeterEffect.Bindable.ValueChanged += volumeChanged;
|
||||
volumeMeterMusic.Bindable.ValueChanged += volumeChanged;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
volumeMeterMaster.Bindable.ValueChanged -= volumeChanged;
|
||||
volumeMeterEffect.Bindable.ValueChanged -= volumeChanged;
|
||||
volumeMeterMusic.Bindable.ValueChanged -= volumeChanged;
|
||||
volumeMeterMaster.Bindable.ValueChanged += _ => settingChanged();
|
||||
volumeMeterEffect.Bindable.ValueChanged += _ => settingChanged();
|
||||
volumeMeterMusic.Bindable.ValueChanged += _ => settingChanged();
|
||||
muted.ValueChanged += _ => settingChanged();
|
||||
}
|
||||
|
||||
public bool Adjust(GlobalAction action)
|
||||
@ -76,23 +81,45 @@ namespace osu.Game.Graphics.UserInterface.Volume
|
||||
else
|
||||
volumeMeterMaster.Increase();
|
||||
return true;
|
||||
case GlobalAction.ToggleMute:
|
||||
Show();
|
||||
muted.Toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void volumeChanged(double newVolume)
|
||||
private void settingChanged()
|
||||
{
|
||||
Show();
|
||||
schedulePopOut();
|
||||
}
|
||||
|
||||
private readonly BindableDouble muteAdjustment = new BindableDouble();
|
||||
|
||||
private readonly BindableBool muted = new BindableBool();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
volumeMeterMaster.Bindable.BindTo(audio.Volume);
|
||||
volumeMeterEffect.Bindable.BindTo(audio.VolumeSample);
|
||||
volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack);
|
||||
|
||||
muted.ValueChanged += mute =>
|
||||
{
|
||||
if (mute)
|
||||
{
|
||||
audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment);
|
||||
muteIcon.Icon = FontAwesome.fa_volume_off;
|
||||
}
|
||||
else
|
||||
{
|
||||
audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment);
|
||||
muteIcon.Icon = FontAwesome.fa_volume_up;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ScheduledDelegate popOutDelegate;
|
||||
|
@ -70,11 +70,8 @@ namespace osu.Game.Graphics.UserInterface.Volume
|
||||
|
||||
public double Volume
|
||||
{
|
||||
get { return Bindable.Value; }
|
||||
private set
|
||||
{
|
||||
Bindable.Value = value;
|
||||
}
|
||||
get => Bindable.Value;
|
||||
private set => Bindable.Value = value;
|
||||
}
|
||||
|
||||
public void Increase()
|
||||
|
@ -29,10 +29,11 @@ namespace osu.Game.Input.Bindings
|
||||
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings),
|
||||
new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar),
|
||||
new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings),
|
||||
new KeyBinding(new[] { InputKey.Up }, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.MouseWheelUp }, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.Down }, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.MouseWheelDown }, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
|
||||
};
|
||||
|
||||
public IEnumerable<KeyBinding> InGameKeyBindings => new[]
|
||||
@ -63,6 +64,8 @@ namespace osu.Game.Input.Bindings
|
||||
IncreaseVolume,
|
||||
[Description("Decrease Volume")]
|
||||
DecreaseVolume,
|
||||
[Description("Toggle mute")]
|
||||
ToggleMute,
|
||||
|
||||
// In-Game Keybindings
|
||||
[Description("Skip Cutscene")]
|
||||
|
25
osu.Game/Migrations/20180131154205_AddMuteBinding.cs
Normal file
25
osu.Game/Migrations/20180131154205_AddMuteBinding.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Input.Bindings;
|
||||
|
||||
namespace osu.Game.Migrations
|
||||
{
|
||||
[DbContext(typeof(OsuDbContext))]
|
||||
[Migration("20180131154205_AddMuteBinding")]
|
||||
public partial class AddMuteBinding : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql($"UPDATE KeyBinding SET Action = Action + 1 WHERE RulesetID IS NULL AND Variant IS NULL AND Action >= {(int)GlobalAction.ToggleMute}");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql($"DELETE FROM KeyBinding WHERE RulesetID IS NULL AND Variant IS NULL AND Action = {(int)GlobalAction.ToggleMute}");
|
||||
migrationBuilder.Sql($"UPDATE KeyBinding SET Action = Action - 1 WHERE RulesetID IS NULL AND Variant IS NULL AND Action > {(int)GlobalAction.ToggleMute}");
|
||||
}
|
||||
}
|
||||
}
|
@ -240,13 +240,13 @@ namespace osu.Game.Rulesets.UI
|
||||
foreach (var mod in Mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
// Post-process the beatmap
|
||||
processor.PostProcess(Beatmap);
|
||||
|
||||
// Apply defaults
|
||||
foreach (var h in Beatmap.HitObjects)
|
||||
h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
// Post-process the beatmap
|
||||
processor.PostProcess(Beatmap);
|
||||
|
||||
KeyBindingInputManager = CreateInputManager();
|
||||
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
|
||||
|
||||
|
@ -136,9 +136,20 @@ namespace osu.Game.Rulesets.UI
|
||||
int loops = 0;
|
||||
|
||||
while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame)
|
||||
{
|
||||
if (!base.UpdateSubTree())
|
||||
return false;
|
||||
|
||||
if (isAttached)
|
||||
{
|
||||
// When handling replay input, we need to consider the possibility of fast-forwarding, which may cause the clock to be updated
|
||||
// to a point very far into the future, then playing a frame at that time. In such a case, lifetime MUST be updated before
|
||||
// input is handled. This is why base.Update is not called from the derived Update when handling replay input, and is instead
|
||||
// called manually at the correct time here.
|
||||
base.Update();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -173,8 +184,11 @@ namespace osu.Game.Rulesets.UI
|
||||
// to ensure that the its time is valid for our children before input is processed
|
||||
Clock.ProcessFrame();
|
||||
|
||||
// Process input
|
||||
base.Update();
|
||||
if (!isAttached)
|
||||
{
|
||||
// For non-replay input handling, this provides equivalent input ordering as if Update was not overridden
|
||||
base.Update();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -209,6 +209,8 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
Action = () =>
|
||||
{
|
||||
if (!IsCurrentScreen) return;
|
||||
|
||||
//we want to hide the hitrenderer immediately (looks better).
|
||||
//we may be able to remove this once the mouse cursor trail is improved.
|
||||
RulesetContainer?.Hide();
|
||||
@ -274,6 +276,8 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
onCompletionEvent = Schedule(delegate
|
||||
{
|
||||
if (!IsCurrentScreen) return;
|
||||
|
||||
var score = new Score
|
||||
{
|
||||
Beatmap = Beatmap.Value.BeatmapInfo,
|
||||
|
@ -280,6 +280,7 @@
|
||||
<Compile Include="Migrations\20180125143340_Settings.Designer.cs">
|
||||
<DependentUpon>20180125143340_Settings.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Migrations\20180131154205_AddMuteBinding.cs" />
|
||||
<Compile Include="Overlays\Profile\SupporterIcon.cs" />
|
||||
<Compile Include="Online\API\Requests\GetFriendsRequest.cs" />
|
||||
<Compile Include="Overlays\Settings\DangerousSettingsButton.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user