Merge https://github.com/ppy/osu into song-progress-graph

This commit is contained in:
DrabWeb
2017-03-22 08:50:17 -03:00
372 changed files with 12163 additions and 3733 deletions

View File

@ -10,7 +10,7 @@ using OpenTK.Graphics;
namespace osu.Game.Screens.Play
{
class FailDialog : OsuScreen
internal class FailDialog : OsuScreen
{
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap);

View File

@ -0,0 +1,16 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Input;
namespace osu.Game.Screens.Play
{
/// <summary>
/// An InputManager primarily used to map keys to new functions.
/// By default this does nothing; override TransformState to make alterations.
/// </summary>
public class KeyConversionInputManager : PassThroughInputManager
{
}
}

View File

@ -19,7 +19,6 @@ namespace osu.Game.Screens.Play
private Container textLayer;
private SpriteText countSpriteText;
public override string Name { get; }
public bool IsCounting { get; set; }
private int count;
public int Count
@ -54,7 +53,7 @@ namespace osu.Game.Screens.Play
//further: change default values here and in KeyCounterCollection if needed, instead of passing them in every constructor
public Color4 KeyDownTextColor { get; set; } = Color4.DarkGray;
public Color4 KeyUpTextColor { get; set; } = Color4.White;
public int FadeTime { get; set; } = 0;
public int FadeTime { get; set; }
protected KeyCounter(string name)
{

View File

@ -1,10 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Input;
namespace osu.Game.Screens.Play
{
@ -12,7 +13,9 @@ namespace osu.Game.Screens.Play
{
public KeyCounterCollection()
{
Direction = FillDirection.Right;
AlwaysReceiveInput = true;
Direction = FillDirection.Horizontal;
AutoSizeAxes = Axes.Both;
}
@ -31,8 +34,6 @@ namespace osu.Game.Screens.Play
counter.ResetCount();
}
public override bool Contains(Vector2 screenSpacePos) => true;
//further: change default values here and in KeyCounter if needed, instead of passing them in every constructor
private bool isCounting;
public bool IsCounting
@ -49,7 +50,7 @@ namespace osu.Game.Screens.Play
}
}
private int fadeTime = 0;
private int fadeTime;
public int FadeTime
{
get { return fadeTime; }
@ -93,5 +94,36 @@ namespace osu.Game.Screens.Play
}
}
}
public override bool HandleInput => receptor?.IsAlive != true;
private Receptor receptor;
public Receptor GetReceptor()
{
return receptor ?? (receptor = new Receptor(this));
}
public class Receptor : Drawable
{
private KeyCounterCollection target;
public Receptor(KeyCounterCollection target)
{
AlwaysReceiveInput = true;
RelativeSizeAxes = Axes.Both;
this.target = target;
}
public override bool HandleInput => true;
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => target.Children.Any(c => c.TriggerKeyDown(state, args));
protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => target.Children.Any(c => c.TriggerKeyUp(state, args));
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => target.Children.Any(c => c.TriggerMouseDown(state, args));
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => target.Children.Any(c => c.TriggerMouseUp(state, args));
}
}
}

View File

@ -9,7 +9,7 @@ namespace osu.Game.Screens.Play
public class KeyCounterKeyboard : KeyCounter
{
public Key Key { get; }
public KeyCounterKeyboard(string name, Key key) : base(name)
public KeyCounterKeyboard(Key key) : base(key.ToString())
{
Key = key;
}

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Input;
using OpenTK;
using OpenTK.Input;
namespace osu.Game.Screens.Play
@ -10,12 +9,25 @@ namespace osu.Game.Screens.Play
public class KeyCounterMouse : KeyCounter
{
public MouseButton Button { get; }
public KeyCounterMouse(string name, MouseButton button) : base(name)
public KeyCounterMouse(MouseButton button) : base(getStringRepresentation(button))
{
AlwaysReceiveInput = true;
Button = button;
}
public override bool Contains(Vector2 screenSpacePos) => true;
private static string getStringRepresentation(MouseButton button)
{
switch (button)
{
default:
return button.ToString();
case MouseButton.Left:
return @"M1";
case MouseButton.Right:
return @"M2";
}
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{

View File

@ -1,26 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens;
using osu.Game.Screens.Backgrounds;
using OpenTK.Graphics;
namespace osu.Game.Screens.Play
{
class ModSelect : ScreenWhiteBox
{
protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4");
protected override void OnEntering(Screen last)
{
base.OnEntering(last);
Background.Schedule(() => Background.FadeColour(Color4.DarkGray, 500));
}
protected override bool OnExiting(Screen next)
{
Background.Schedule(() => Background.FadeColour(Color4.White, 500));
return base.OnExiting(next);
}
}
}

View File

@ -0,0 +1,150 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using OpenTK.Graphics;
namespace osu.Game.Screens.Play.Pause
{
public class PauseProgressBar : Container
{
private Color4 fillColour = new Color4(221, 255, 255, 255);
private Color4 glowColour = new Color4(221, 255, 255, 150);
private Container fill;
private WorkingBeatmap current;
[BackgroundDependencyLoader]
private void load(OsuGameBase osuGame)
{
current = osuGame.Beatmap.Value;
}
protected override void Update()
{
base.Update();
if (current?.TrackLoaded ?? false)
{
fill.Width = (float)(current.Track.CurrentTime / current.Track.Length);
}
}
public PauseProgressBar()
{
RelativeSizeAxes = Axes.X;
Height = 60;
Children = new Drawable[]
{
new PauseProgressGraph
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Height = 35,
Margin = new MarginPadding
{
Bottom = 5
}
},
new Container
{
Origin = Anchor.BottomRight,
Anchor = Anchor.BottomRight,
RelativeSizeAxes = Axes.X,
Height = 5,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = 0.5f
}
}
},
fill = new Container
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Width = 0,
Height = 60,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Masking = true,
Children = new Drawable[]
{
new Container
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
RelativeSizeAxes = Axes.X,
Height = 5,
Masking = true,
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Glow,
Colour = glowColour,
Radius = 5
},
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = fillColour
}
}
}
}
},
new Container
{
Origin = Anchor.BottomRight,
Anchor = Anchor.BottomRight,
Width = 2,
Height = 35,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White
},
new Container
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.TopCentre,
Width = 14,
Height = 25,
CornerRadius = 5,
Masking = true,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White
}
}
}
}
}
}
}
};
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Containers;
namespace osu.Game.Screens.Play.Pause
{
public class PauseProgressGraph : Container
{
// TODO: Implement the pause progress graph
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Game.Graphics.UserInterface;
using OpenTK.Graphics;
namespace osu.Game.Screens.Play.Pause
{
public class QuitButton : DialogButton
{
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
ButtonColour = new Color4(170, 27, 39, 255); // The red from the design isn't in the palette so it's used directly
SampleHover = audio.Sample.Get(@"Menu/menuclick");
SampleClick = audio.Sample.Get(@"Menu/menuback");
}
public QuitButton()
{
Text = @"Quit to Main Menu";
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Screens.Play.Pause
{
public class ResumeButton : DialogButton
{
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuColour colours)
{
ButtonColour = colours.Green;
SampleHover = audio.Sample.Get(@"Menu/menuclick");
SampleClick = audio.Sample.Get(@"Menu/menuback");
}
public ResumeButton()
{
Text = @"Continue";
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Screens.Play.Pause
{
public class RetryButton : DialogButton
{
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuColour colours)
{
ButtonColour = colours.YellowDark;
SampleHover = audio.Sample.Get(@"Menu/menuclick");
SampleClick = audio.Sample.Get(@"Menu/menu-play-click");
}
public RetryButton()
{
Text = @"Retry";
}
}
}

View File

@ -0,0 +1,219 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// 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;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Play.Pause;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
namespace osu.Game.Screens.Play
{
public class PauseOverlay : OverlayContainer
{
private const int transition_duration = 200;
private const int button_height = 70;
private const float background_alpha = 0.75f;
protected override bool HideOnEscape => false;
public Action OnResume;
public Action OnRetry;
public Action OnQuit;
public int Retries
{
set
{
if (retryCounterContainer != null)
{
// "You've retried 1,065 times in this session"
// "You've retried 1 time in this session"
retryCounterContainer.Children = new Drawable[]
{
new OsuSpriteText
{
Text = "You've retried ",
Shadow = true,
ShadowColour = new Color4(0, 0, 0, 0.25f),
TextSize = 18
},
new OsuSpriteText
{
Text = $"{value:n0}",
Font = @"Exo2.0-Bold",
Shadow = true,
ShadowColour = new Color4(0, 0, 0, 0.25f),
TextSize = 18
},
new OsuSpriteText
{
Text = $" time{(value == 1 ? "" : "s")} in this session",
Shadow = true,
ShadowColour = new Color4(0, 0, 0, 0.25f),
TextSize = 18
}
};
}
}
}
private FillFlowContainer retryCounterContainer;
public override bool HandleInput => State == Visibility.Visible;
protected override void PopIn() => FadeIn(transition_duration, EasingTypes.In);
protected override void PopOut() => FadeOut(transition_duration, EasingTypes.In);
// Don't let mouse down events through the overlay or people can click circles while paused.
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true;
protected override bool OnMouseMove(InputState state) => true;
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (args.Key == Key.Escape)
{
if (State == Visibility.Hidden) return false;
resume();
return true;
}
return base.OnKeyDown(state, args);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Alpha = background_alpha,
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 50),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Children = new Drawable[]
{
new FillFlowContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 20),
Children = new Drawable[]
{
new OsuSpriteText
{
Text = @"paused",
Font = @"Exo2.0-Medium",
Spacing = new Vector2(5, 0),
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
TextSize = 30,
Colour = colours.Yellow,
Shadow = true,
ShadowColour = new Color4(0, 0, 0, 0.25f)
},
new OsuSpriteText
{
Text = @"you're not going to do what i think you're going to do, are ya?",
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Shadow = true,
ShadowColour = new Color4(0, 0, 0, 0.25f)
}
}
},
new FillFlowContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Masking = true,
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.6f),
Radius = 50
},
Children = new Drawable[]
{
new ResumeButton
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Height = button_height,
Action = resume
},
new RetryButton
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Height = button_height,
Action = delegate
{
OnRetry?.Invoke();
Hide();
}
},
new QuitButton
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Height = button_height,
Action = delegate
{
OnQuit?.Invoke();
Hide();
}
}
}
},
retryCounterContainer = new FillFlowContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
}
}
}
};
Retries = 0;
}
private void resume()
{
OnResume?.Invoke();
Hide();
}
public PauseOverlay()
{
AlwaysReceiveInput = true;
RelativeSizeAxes = Axes.Both;
}
}
}

View File

@ -1,62 +1,54 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Timing;
using osu.Game.Database;
using osu.Game.Modes;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Screens.Backgrounds;
using OpenTK;
using osu.Framework.Screens;
using osu.Game.Modes.UI;
using osu.Game.Screens.Ranking;
using osu.Game.Configuration;
using osu.Game.Overlays.Pause;
using osu.Framework.Configuration;
using System;
using System.Linq;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Logging;
using osu.Framework.Input;
using osu.Framework.Logging;
using osu.Framework.Screens;
using osu.Framework.Timing;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Input.Handlers;
using osu.Game.Modes;
using osu.Game.Modes.UI;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Ranking;
using System;
using System.Linq;
namespace osu.Game.Screens.Play
{
public class Player : OsuScreen
{
public bool Autoplay;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap);
internal override bool ShowOverlays => false;
internal override bool HasLocalCursorDisplayed => !hasReplayLoaded && !IsPaused;
private bool hasReplayLoaded => hitRenderer.InputManager.ReplayInputHandler != null;
public BeatmapInfo BeatmapInfo;
public PlayMode PreferredPlayMode;
private bool isPaused;
public bool IsPaused
{
get
{
return isPaused;
}
}
public bool IsPaused { get; private set; }
public int RestartCount;
private double pauseCooldown = 1000;
private double lastPauseActionTime = 0;
private double lastPauseActionTime;
private bool canPause => Time.Current >= (lastPauseActionTime + pauseCooldown);
private bool canPause => Time.Current >= lastPauseActionTime + pauseCooldown;
private IAdjustableClock sourceClock;
private IFrameBasedClock interpolatedSourceClock;
private Ruleset ruleset;
@ -65,13 +57,21 @@ namespace osu.Game.Screens.Play
private Bindable<int> dimLevel;
private SkipButton skipButton;
private ScoreOverlay scoreOverlay;
private HudOverlay hudOverlay;
private PauseOverlay pauseOverlay;
private PlayerInputManager playerInputManager;
[BackgroundDependencyLoader]
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuGameBase game, OsuConfigManager config)
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config)
{
var beatmap = Beatmap.Beatmap;
if (beatmap.BeatmapInfo?.Mode > PlayMode.Osu)
{
//we only support osu! mode for now because the hitobject parsing is crappy and needs a refactor.
Exit();
return;
}
dimLevel = config.GetBindable<int>(OsuConfig.DimLevel);
mouseWheelDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableWheel);
@ -82,6 +82,9 @@ namespace osu.Game.Screens.Play
if ((Beatmap?.Beatmap?.HitObjects.Count ?? 0) == 0)
throw new Exception("No valid objects were found!");
if (Beatmap == null)
throw new Exception("Beatmap was not loaded");
}
catch (Exception e)
{
@ -101,27 +104,21 @@ namespace osu.Game.Screens.Play
}
sourceClock = (IAdjustableClock)track ?? new StopwatchClock();
interpolatedSourceClock = new InterpolatingFramedClock(sourceClock);
Schedule(() =>
{
sourceClock.Reset();
});
var beatmap = Beatmap.Beatmap;
ruleset = Ruleset.GetRuleset(Beatmap.PlayMode);
hitRenderer = ruleset.CreateHitRendererWith(Beatmap);
if (beatmap.BeatmapInfo?.Mode > PlayMode.Osu)
{
//we only support osu! mode for now because the hitobject parsing is crappy and needs a refactor.
Exit();
return;
}
scoreProcessor = hitRenderer.CreateScoreProcessor();
PlayMode usablePlayMode = beatmap.BeatmapInfo?.Mode > PlayMode.Osu ? beatmap.BeatmapInfo.Mode : PreferredPlayMode;
ruleset = Ruleset.GetRuleset(usablePlayMode);
scoreOverlay = ruleset.CreateScoreOverlay();
scoreOverlay.BindProcessor(scoreProcessor = ruleset.CreateScoreProcessor(beatmap.HitObjects.Count));
hudOverlay = new StandardHudOverlay();
hudOverlay.KeyCounter.Add(ruleset.CreateGameplayKeys());
hudOverlay.BindProcessor(scoreProcessor);
pauseOverlay = new PauseOverlay
{
@ -135,30 +132,34 @@ namespace osu.Game.Screens.Play
OnQuit = Exit
};
hitRenderer = ruleset.CreateHitRendererWith(beatmap);
if (ReplayInputHandler != null)
hitRenderer.InputManager.ReplayInputHandler = ReplayInputHandler;
hudOverlay.BindHitRenderer(hitRenderer);
//bind HitRenderer to ScoreProcessor and ourselves (for a pass situation)
hitRenderer.OnJudgement += scoreProcessor.AddJudgement;
hitRenderer.OnAllJudged += onPass;
hitRenderer.OnAllJudged += onCompletion;
//bind ScoreProcessor to ourselves (for a fail situation)
scoreProcessor.Failed += onFail;
if (Autoplay)
hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Hit));
Children = new Drawable[]
{
playerInputManager = new PlayerInputManager(game.Host)
new Container
{
Clock = new InterpolatingFramedClock(sourceClock),
RelativeSizeAxes = Axes.Both,
Clock = interpolatedSourceClock,
Children = new Drawable[]
{
hitRenderer,
skipButton = new SkipButton { Alpha = 0 },
skipButton = new SkipButton
{
Alpha = 0
},
}
},
scoreOverlay,
hudOverlay,
pauseOverlay
};
}
@ -195,30 +196,30 @@ namespace osu.Game.Screens.Play
if (canPause || force)
{
lastPauseActionTime = Time.Current;
scoreOverlay.KeyCounter.IsCounting = false;
hudOverlay.KeyCounter.IsCounting = false;
pauseOverlay.Retries = RestartCount;
pauseOverlay.Show();
sourceClock.Stop();
isPaused = true;
IsPaused = true;
}
else
{
isPaused = false;
IsPaused = false;
}
}
public void Resume()
{
lastPauseActionTime = Time.Current;
scoreOverlay.KeyCounter.IsCounting = true;
hudOverlay.KeyCounter.IsCounting = true;
pauseOverlay.Hide();
sourceClock.Start();
isPaused = false;
IsPaused = false;
}
public void TogglePaused()
{
isPaused = !IsPaused;
IsPaused = !IsPaused;
if (IsPaused) Pause(); else Resume();
}
@ -240,15 +241,19 @@ namespace osu.Game.Screens.Play
});
}
private void onPass()
private void onCompletion()
{
// Only show the completion screen if the player hasn't failed
if (scoreProcessor.HasFailed)
return;
Delay(1000);
Schedule(delegate
{
ValidForResume = false;
Push(new Results
{
Score = scoreProcessor.GetScore()
Score = scoreProcessor.CreateScore()
});
});
}
@ -303,6 +308,9 @@ namespace osu.Game.Screens.Play
{
if (pauseOverlay == null) return false;
if (hasReplayLoaded)
return false;
if (pauseOverlay.State != Visibility.Visible && !canPause) return true;
if (!IsPaused && sourceClock.IsRunning) // For if the user presses escape quickly when entering the map
@ -328,6 +336,8 @@ namespace osu.Game.Screens.Play
private Bindable<bool> mouseWheelDisabled;
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !isPaused;
public ReplayInputHandler ReplayInputHandler;
protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !IsPaused;
}
}

View File

@ -1,57 +1,71 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Input;
using osu.Framework.Platform;
using osu.Game.Configuration;
using System.Linq;
using osu.Framework.Timing;
using osu.Game.Input.Handlers;
namespace osu.Game.Screens.Play
{
class PlayerInputManager : UserInputManager
public class PlayerInputManager : PassThroughInputManager
{
public PlayerInputManager(GameHost host)
: base(host)
private ManualClock clock = new ManualClock();
private IFrameBasedClock parentClock;
private ReplayInputHandler replayInputHandler;
public ReplayInputHandler ReplayInputHandler
{
}
bool leftViaKeyboard;
bool rightViaKeyboard;
Bindable<bool> mouseDisabled;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
mouseDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableButtons)
?? new Bindable<bool>(false);
}
protected override void TransformState(InputState state)
{
base.TransformState(state);
if (state.Keyboard != null)
get { return replayInputHandler; }
set
{
leftViaKeyboard = state.Keyboard.Keys.Contains(Key.Z);
rightViaKeyboard = state.Keyboard.Keys.Contains(Key.X);
if (replayInputHandler != null) RemoveHandler(replayInputHandler);
replayInputHandler = value;
UseParentState = replayInputHandler == null;
if (replayInputHandler != null)
AddHandler(replayInputHandler);
}
}
protected override void LoadComplete()
{
base.LoadComplete();
parentClock = Clock;
Clock = new FramedClock(clock);
}
protected override void Update()
{
base.Update();
if (parentClock == null) return;
clock.Rate = parentClock.Rate;
clock.IsRunning = parentClock.IsRunning;
//if a replayHandler is not attached, we should just pass-through.
if (UseParentState || replayInputHandler == null)
{
clock.CurrentTime = parentClock.CurrentTime;
base.Update();
return;
}
var mouse = (Framework.Input.MouseState)state.Mouse;
if (state.Mouse != null)
while (true)
{
if (mouseDisabled.Value)
{
mouse.ButtonStates.Find(s => s.Button == MouseButton.Left).State = false;
mouse.ButtonStates.Find(s => s.Button == MouseButton.Right).State = false;
}
double? newTime = replayInputHandler.SetFrameFromTime(parentClock.CurrentTime);
if (leftViaKeyboard)
mouse.ButtonStates.Find(s => s.Button == MouseButton.Left).State = true;
if (rightViaKeyboard)
mouse.ButtonStates.Find(s => s.Button == MouseButton.Right).State = true;
if (newTime == null)
//we shouldn't execute for this time value
break;
if (clock.CurrentTime == parentClock.CurrentTime)
break;
clock.CurrentTime = newTime.Value;
base.Update();
}
}
}

View File

@ -95,9 +95,9 @@ namespace osu.Game.Screens.Play
return base.OnExiting(next);
}
class BeatmapMetadataDisplay : Container
private class BeatmapMetadataDisplay : Container
{
class MetadataLine : Container
private class MetadataLine : Container
{
public MetadataLine(string left, string right)
{
@ -131,12 +131,12 @@ namespace osu.Game.Screens.Play
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
{
new FillFlowContainer()
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Direction = FillDirection.Down,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new OsuSpriteText
@ -167,7 +167,7 @@ namespace osu.Game.Screens.Play
{
new Sprite
{
Texture = beatmap.Background,
Texture = beatmap?.Background,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
FillMode = FillMode.Fill,
@ -176,7 +176,7 @@ namespace osu.Game.Screens.Play
},
new OsuSpriteText
{
Text = beatmap.BeatmapInfo?.Version,
Text = beatmap?.BeatmapInfo?.Version,
TextSize = 26,
Font = @"Exo2.0-MediumItalic",
Origin = Anchor.TopCentre,

View File

@ -4,9 +4,9 @@
using OpenTK;
using OpenTK.Graphics;
using System.Collections.Generic;
using osu.Game.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Screens.Play
{