示例#1
0
        private Drawable createOverlayComponents(WorkingBeatmap working)
        {
            var container = new Container
            {
                RelativeSizeAxes = Axes.Both,
                Children         = new[]
                {
                    DimmableStoryboard.OverlayLayerContainer.CreateProxy(),
                BreakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
                    {
                        Clock = DrawableRuleset.FrameStableClock,
                        ProcessCustomClock = false,
                        Breaks             = working.Beatmap.Breaks
                    },
                    // display the cursor above some HUD elements.
                DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
                DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(),
                HUDOverlay = new HUDOverlay(ScoreProcessor, HealthProcessor, DrawableRuleset, Mods.Value)
                    {
                        HoldToQuit =
                        {
                            Action   = performUserRequestedExit,
                            IsPaused = { BindTarget = GameplayClockContainer.IsPaused }
                        },
                        PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } },
                        KeyCounter            =
                        {
                            AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded },
                            IsCounting    = false
                        },
                        RequestSeek = time =>
                        {
                            GameplayClockContainer.Seek(time);
                            GameplayClockContainer.Start();
                        },
                        Anchor = Anchor.Centre,
                        Origin = Anchor.Centre
                    },
                    skipOverlay = new SkipOverlay(DrawableRuleset.GameplayStartTime)
                    {
                        RequestSkip = GameplayClockContainer.Skip
                    },
                    FailOverlay = new FailOverlay
                    {
                        OnRetry = Restart,
                        OnQuit  = performUserRequestedExit,
                    },
                    PauseOverlay = new PauseOverlay
                    {
                        OnResume = Resume,
                        Retries  = RestartCount,
                        OnRetry  = Restart,
                        OnQuit   = performUserRequestedExit,
                    },
                    new HotkeyExitOverlay
                    {
                        Action = () =>
                        {
                            if (!this.IsCurrentScreen())
                            {
                                return;
                            }

                            fadeOut(true);
                            PerformExit(true);
                        },
                    },
                    failAnimation = new FailAnimation(DrawableRuleset)
                    {
                        OnComplete = onFailComplete,
                    },
                }
            };

            if (!Configuration.AllowSkippingIntro)
            {
                skipOverlay.Expire();
            }

            if (Configuration.AllowRestart)
            {
                container.Add(new HotkeyRetryOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        Restart();
                    },
                });
            }

            return(container);
        }
示例#2
0
        private void load(AudioManager audio, IAPIProvider api, OsuConfigManager config)
        {
            this.api = api;

            Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray();

            WorkingBeatmap working = loadBeatmap();

            if (working == null)
            {
                return;
            }

            sampleRestart = audio.Samples.Get(@"Gameplay/restart");

            mouseWheelDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableWheel);
            showStoryboard     = config.GetBindable <bool>(OsuSetting.ShowStoryboard);

            ScoreProcessor = DrawableRuleset.CreateScoreProcessor();
            ScoreProcessor.Mods.BindTo(Mods);

            if (!ScoreProcessor.Mode.Disabled)
            {
                config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
            }

            InternalChild = GameplayClockContainer = new GameplayClockContainer(working, Mods.Value, DrawableRuleset.GameplayStartTime);

            GameplayClockContainer.Children = new[]
            {
                StoryboardContainer = CreateStoryboardContainer(),
                new ScalingContainer(ScalingMode.Gameplay)
                {
                    Child = new LocalSkinOverrideContainer(working.Skin)
                    {
                        RelativeSizeAxes = Axes.Both,
                        Child            = DrawableRuleset
                    }
                },
                new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
                {
                    Anchor = Anchor.Centre,
                    Origin = Anchor.Centre,
                    Breaks = working.Beatmap.Breaks
                },
                // display the cursor above some HUD elements.
                DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
                HUDOverlay = new HUDOverlay(ScoreProcessor, DrawableRuleset, Mods.Value)
                {
                    HoldToQuit =
                    {
                        Action   = performUserRequestedExit,
                        IsPaused = { BindTarget = GameplayClockContainer.IsPaused }
                    },
                    PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } },
                    KeyCounter            = { Visible = { BindTarget = DrawableRuleset.HasReplayLoaded } },
                    RequestSeek           = GameplayClockContainer.Seek,
                    Anchor = Anchor.Centre,
                    Origin = Anchor.Centre
                },
                new SkipOverlay(DrawableRuleset.GameplayStartTime)
                {
                    RequestSeek = GameplayClockContainer.Seek
                },
                FailOverlay = new FailOverlay
                {
                    OnRetry = Restart,
                    OnQuit  = performUserRequestedExit,
                },
                PauseOverlay = new PauseOverlay
                {
                    OnResume = Resume,
                    Retries  = RestartCount,
                    OnRetry  = Restart,
                    OnQuit   = performUserRequestedExit,
                },
                new HotkeyRetryOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        Restart();
                    },
                },
                new HotkeyExitOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        performUserRequestedExit();
                    },
                },
                failAnimation = new FailAnimation(DrawableRuleset)
                {
                    OnComplete = onFailComplete,
                }
            };

            DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true);

            // bind clock into components that require it
            DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);

            // load storyboard as part of player's load if we can
            initializeStoryboard(false);

            // Bind ScoreProcessor to ourselves
            ScoreProcessor.AllJudged += onCompletion;
            ScoreProcessor.Failed    += onFail;

            foreach (var mod in Mods.Value.OfType <IApplicableToScoreProcessor>())
            {
                mod.ApplyToScoreProcessor(ScoreProcessor);
            }
        }
示例#3
0
        private void addOverlayComponents(Container target, WorkingBeatmap working)
        {
            target.AddRange(new[]
            {
                BreakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
                {
                    Clock = DrawableRuleset.FrameStableClock,
                    ProcessCustomClock = false,
                    Breaks             = working.Beatmap.Breaks
                },
                // display the cursor above some HUD elements.
                DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
                DrawableRuleset.ResumeOverlay?.CreateProxy() ?? new Container(),
                HUDOverlay = new HUDOverlay(ScoreProcessor, HealthProcessor, DrawableRuleset, Mods.Value)
                {
                    HoldToQuit =
                    {
                        Action   = performUserRequestedExit,
                        IsPaused = { BindTarget = GameplayClockContainer.IsPaused }
                    },
                    PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } },
                    KeyCounter            =
                    {
                        AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded },
                        IsCounting    = false
                    },
                    RequestSeek = GameplayClockContainer.Seek,
                    Anchor      = Anchor.Centre,
                    Origin      = Anchor.Centre
                },
                new SkipOverlay(DrawableRuleset.GameplayStartTime)
                {
                    RequestSkip = GameplayClockContainer.Skip
                },
                FailOverlay = new FailOverlay
                {
                    OnRetry = Restart,
                    OnQuit  = performUserRequestedExit,
                },
                PauseOverlay = new PauseOverlay
                {
                    OnResume = Resume,
                    Retries  = RestartCount,
                    OnRetry  = Restart,
                    OnQuit   = performUserRequestedExit,
                },
                new HotkeyRetryOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        Restart();
                    },
                },
                new HotkeyExitOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        performImmediateExit();
                    },
                },
                failAnimation = new FailAnimation(DrawableRuleset)
                {
                    OnComplete = onFailComplete,
                },
            });
        }
示例#4
0
        private void load(AudioManager audio, OsuConfigManager config, OsuGameBase game)
        {
            var gameplayMods = Mods.Value.Select(m => m.DeepClone()).ToArray();

            if (Beatmap.Value is DummyWorkingBeatmap)
            {
                return;
            }

            IBeatmap playableBeatmap = loadPlayableBeatmap(gameplayMods);

            if (playableBeatmap == null)
            {
                return;
            }

            sampleRestart = audio.Samples.Get(@"Gameplay/restart");

            mouseWheelDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableWheel);

            if (game != null)
            {
                gameActive.BindTo(game.IsActive);
            }

            if (game is OsuGame osuGame)
            {
                LocalUserPlaying.BindTo(osuGame.LocalUserPlaying);
            }

            DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods);
            dependencies.CacheAs(DrawableRuleset);

            ScoreProcessor = ruleset.CreateScoreProcessor();
            ScoreProcessor.ApplyBeatmap(playableBeatmap);
            ScoreProcessor.Mods.Value = gameplayMods;

            dependencies.CacheAs(ScoreProcessor);

            HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
            HealthProcessor.ApplyBeatmap(playableBeatmap);

            dependencies.CacheAs(HealthProcessor);

            if (!ScoreProcessor.Mode.Disabled)
            {
                config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
            }

            InternalChild = GameplayClockContainer = CreateGameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime);

            AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer));

            Score = CreateScore(playableBeatmap);

            // ensure the score is in a consistent state with the current player.
            Score.ScoreInfo.BeatmapInfo = Beatmap.Value.BeatmapInfo;
            Score.ScoreInfo.Ruleset     = ruleset.RulesetInfo;
            if (ruleset.RulesetInfo.ID != null)
            {
                Score.ScoreInfo.RulesetID = ruleset.RulesetInfo.ID.Value;
            }
            Score.ScoreInfo.Mods = gameplayMods;

            dependencies.CacheAs(GameplayState = new GameplayState(playableBeatmap, ruleset, gameplayMods, Score));

            var rulesetSkinProvider = new RulesetSkinProvidingContainer(ruleset, playableBeatmap, Beatmap.Value.Skin);

            // load the skinning hierarchy first.
            // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
            GameplayClockContainer.Add(rulesetSkinProvider);

            rulesetSkinProvider.AddRange(new Drawable[]
            {
                failAnimationLayer = new FailAnimation(DrawableRuleset)
                {
                    OnComplete = onFailComplete,
                    Children   = new[]
                    {
                        // underlay and gameplay should have access to the skinning sources.
                        createUnderlayComponents(),
                        createGameplayComponents(Beatmap.Value, playableBeatmap)
                    }
                },
                FailOverlay = new FailOverlay
                {
                    OnRetry = Restart,
                    OnQuit  = () => PerformExit(true),
                },
                new HotkeyExitOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        PerformExit(false);
                    },
                },
            });

            if (Configuration.AllowRestart)
            {
                rulesetSkinProvider.Add(new HotkeyRetryOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        Restart();
                    },
                });
            }

            // add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components.
            // also give the overlays the ruleset skin provider to allow rulesets to potentially override HUD elements (used to disable combo counters etc.)
            // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there.
            failAnimationLayer.Add(createOverlayComponents(Beatmap.Value));

            if (!DrawableRuleset.AllowGameplayOverlays)
            {
                HUDOverlay.ShowHud.Value    = false;
                HUDOverlay.ShowHud.Disabled = true;
                BreakOverlay.Hide();
            }

            DrawableRuleset.FrameStableClock.WaitingOnFrames.BindValueChanged(waiting =>
            {
                if (waiting.NewValue)
                {
                    GameplayClockContainer.Stop();
                }
                else
                {
                    GameplayClockContainer.Start();
                }
            });

            DrawableRuleset.IsPaused.BindValueChanged(paused =>
            {
                updateGameplayState();
                updateSampleDisabledState();
            });

            DrawableRuleset.FrameStableClock.IsCatchingUp.BindValueChanged(_ => updateSampleDisabledState());

            DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());

            // bind clock into components that require it
            DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);

            DrawableRuleset.NewResult += r =>
            {
                HealthProcessor.ApplyResult(r);
                ScoreProcessor.ApplyResult(r);
                GameplayState.ApplyResult(r);
            };

            DrawableRuleset.RevertResult += r =>
            {
                HealthProcessor.RevertResult(r);
                ScoreProcessor.RevertResult(r);
            };

            DimmableStoryboard.HasStoryboardEnded.ValueChanged += storyboardEnded =>
            {
                if (storyboardEnded.NewValue)
                {
                    progressToResults(true);
                }
            };

            // Bind the judgement processors to ourselves
            ScoreProcessor.HasCompleted.BindValueChanged(scoreCompletionChanged);
            HealthProcessor.Failed += onFail;

            // Provide judgement processors to mods after they're loaded so that they're on the gameplay clock,
            // this is required for mods that apply transforms to these processors.
            ScoreProcessor.OnLoadComplete += _ =>
            {
                foreach (var mod in gameplayMods.OfType <IApplicableToScoreProcessor>())
                {
                    mod.ApplyToScoreProcessor(ScoreProcessor);
                }
            };

            HealthProcessor.OnLoadComplete += _ =>
            {
                foreach (var mod in gameplayMods.OfType <IApplicableToHealthProcessor>())
                {
                    mod.ApplyToHealthProcessor(HealthProcessor);
                }
            };

            IsBreakTime.BindTo(breakTracker.IsBreakTime);
            IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
        }