예제 #1
0
 public PippidonScoreProcessor(RulesetContainer <PippidonObject> ruleset) : base(ruleset)
 {
 }
예제 #2
0
 public override void ApplyToRulesetContainer(RulesetContainer <CatchHitObject> rulesetContainer)
 {
     playfield = (CatchPlayfield)rulesetContainer.Playfield;
     base.ApplyToRulesetContainer(rulesetContainer);
 }
예제 #3
0
 public OsuScoreProcessor(RulesetContainer <OsuHitObject> rulesetContainer)
     : base(rulesetContainer)
 {
 }
예제 #4
0
파일: SongProgress.cs 프로젝트: pujitm/osu
 public void BindRulestContainer(RulesetContainer rulesetContainer)
 {
     replayLoaded.BindTo(rulesetContainer.HasReplayLoaded);
 }
예제 #5
0
 public TaikoScoreProcessor(RulesetContainer <TaikoHitObject> rulesetContainer)
     : base(rulesetContainer)
 {
 }
 public KaraokeScoreProcessor(RulesetContainer <Lyric> rulesetContainer)
     : base(rulesetContainer)
 {
 }
예제 #7
0
 public void ApplyToRulesetContainer(RulesetContainer <OsuHitObject> rulesetContainer)
 {
     rulesetContainer.Overlays.Add(blinds = new DrawableOsuBlinds(rulesetContainer.Playfield.HitObjectContainer, rulesetContainer.Beatmap));
 }
예제 #8
0
        private void load(OsuGameBase osuGame)
        {
            try
            {
                rulesetContainer = CreateRulesetContainer(ruleset, osuGame.Beatmap.Value);

                // TODO: should probably be done at a RulesetContainer level to share logic with Player.
                rulesetContainer.Clock = new InterpolatingFramedClock((IAdjustableClock)osuGame.Beatmap.Value.Track ?? new StopwatchClock());
            }
            catch (Exception e)
            {
                Logger.Error(e, "Could not load beatmap sucessfully!");
                return;
            }

            HitObjectOverlayLayer hitObjectOverlayLayer = CreateHitObjectOverlayLayer();
            SelectionLayer        selectionLayer        = new SelectionLayer(rulesetContainer.Playfield);

            var layerBelowRuleset = new BorderLayer
            {
                RelativeSizeAxes = Axes.Both,
                Child            = CreateLayerContainer()
            };

            var layerAboveRuleset = CreateLayerContainer();

            layerAboveRuleset.Children = new Drawable[]
            {
                selectionLayer,              // Below object overlays for input
                hitObjectOverlayLayer,
                selectionLayer.CreateProxy() // Proxy above object overlays for selections
            };

            layerContainers.Add(layerBelowRuleset);
            layerContainers.Add(layerAboveRuleset);

            RadioButtonCollection toolboxCollection;

            InternalChild = new GridContainer
            {
                RelativeSizeAxes = Axes.Both,
                Content          = new[]
                {
                    new Drawable[]
                    {
                        new FillFlowContainer
                        {
                            Name             = "Sidebar",
                            RelativeSizeAxes = Axes.Both,
                            Padding          = new MarginPadding {
                                Right = 10
                            },
                            Children = new Drawable[]
                            {
                                new ToolboxGroup {
                                    Child = toolboxCollection = new RadioButtonCollection {
                                        RelativeSizeAxes = Axes.X
                                    }
                                }
                            }
                        },
                        new Container
                        {
                            Name             = "Content",
                            RelativeSizeAxes = Axes.Both,
                            Children         = new Drawable[]
                            {
                                layerBelowRuleset,
                                rulesetContainer,
                                layerAboveRuleset
                            }
                        }
                    },
                },
                ColumnDimensions = new[]
                {
                    new Dimension(GridSizeMode.Absolute, 200),
                }
            };

            selectionLayer.ObjectSelected   += hitObjectOverlayLayer.AddOverlay;
            selectionLayer.ObjectDeselected += hitObjectOverlayLayer.RemoveOverlay;

            toolboxCollection.Items =
                new[] { new RadioButton("Select", () => setCompositionTool(null)) }
            .Concat(
                CompositionTools.Select(t => new RadioButton(t.Name, () => setCompositionTool(t)))
                )
            .ToList();

            toolboxCollection.Items[0].Select();
        }
예제 #9
0
        private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
        {
            this.api = api;

            WorkingBeatmap working = loadBeatmap();

            if (working == null)
            {
                return;
            }

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

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

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

            InternalChild = gameplayClockContainer = new GameplayClockContainer(working, AllowLeadIn, RulesetContainer.GameplayStartTime);

            gameplayClockContainer.Children = new Drawable[]
            {
                PausableGameplayContainer = new PausableGameplayContainer
                {
                    Retries       = RestartCount,
                    OnRetry       = restart,
                    OnQuit        = performUserRequestedExit,
                    Start         = gameplayClockContainer.Start,
                    Stop          = gameplayClockContainer.Stop,
                    IsPaused      = { BindTarget = gameplayClockContainer.IsPaused },
                    CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded.Value,
                    Children      = new[]
                    {
                        StoryboardContainer = CreateStoryboardContainer(),
                        new ScalingContainer(ScalingMode.Gameplay)
                        {
                            Child = new LocalSkinOverrideContainer(working.Skin)
                            {
                                RelativeSizeAxes = Axes.Both,
                                Child            = RulesetContainer
                            }
                        },
                        new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
                        {
                            Anchor = Anchor.Centre,
                            Origin = Anchor.Centre,
                            Breaks = working.Beatmap.Breaks
                        },
                        // display the cursor above some HUD elements.
                        RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
                        HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working)
                        {
                            HoldToQuit            = { Action = performUserRequestedExit },
                            PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = gameplayClockContainer.UserPlaybackRate } } },
                            KeyCounter            = { Visible = { BindTarget = RulesetContainer.HasReplayLoaded } },
                            RequestSeek           = gameplayClockContainer.Seek,
                            Anchor = Anchor.Centre,
                            Origin = Anchor.Centre
                        },
                        new SkipOverlay(RulesetContainer.GameplayStartTime)
                        {
                            RequestSeek = gameplayClockContainer.Seek
                        },
                    }
                },
                failOverlay = new FailOverlay
                {
                    OnRetry = restart,
                    OnQuit  = performUserRequestedExit,
                },
                new HotkeyRetryOverlay
                {
                    Action = () =>
                    {
                        if (!this.IsCurrentScreen())
                        {
                            return;
                        }

                        fadeOut(true);
                        restart();
                    },
                }
            };

            // bind clock into components that require it
            RulesetContainer.IsPaused.BindTo(gameplayClockContainer.IsPaused);

            if (ShowStoryboard.Value)
            {
                initializeStoryboard(false);
            }

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

            foreach (var mod in Beatmap.Value.Mods.Value.OfType <IApplicableToScoreProcessor>())
            {
                mod.ApplyToScoreProcessor(ScoreProcessor);
            }
        }
예제 #10
0
        private void load(OsuGameBase osuGame, IFrameBasedClock framedClock)
        {
            beatmap.BindTo(osuGame.Beatmap);

            try
            {
                rulesetContainer       = CreateRulesetContainer(ruleset, beatmap.Value);
                rulesetContainer.Clock = framedClock;
            }
            catch (Exception e)
            {
                Logger.Error(e, "Could not load beatmap sucessfully!");
                return;
            }

            var layerBelowRuleset = new BorderLayer
            {
                RelativeSizeAxes = Axes.Both,
                Child            = CreateLayerContainer()
            };

            var layerAboveRuleset = CreateLayerContainer();

            layerAboveRuleset.Child = new HitObjectMaskLayer(rulesetContainer.Playfield, this);

            layerContainers.Add(layerBelowRuleset);
            layerContainers.Add(layerAboveRuleset);

            RadioButtonCollection toolboxCollection;

            InternalChild = new GridContainer
            {
                RelativeSizeAxes = Axes.Both,
                Content          = new[]
                {
                    new Drawable[]
                    {
                        new FillFlowContainer
                        {
                            Name             = "Sidebar",
                            RelativeSizeAxes = Axes.Both,
                            Padding          = new MarginPadding {
                                Right = 10
                            },
                            Children = new Drawable[]
                            {
                                new ToolboxGroup {
                                    Child = toolboxCollection = new RadioButtonCollection {
                                        RelativeSizeAxes = Axes.X
                                    }
                                }
                            }
                        },
                        new Container
                        {
                            Name             = "Content",
                            RelativeSizeAxes = Axes.Both,
                            Children         = new Drawable[]
                            {
                                layerBelowRuleset,
                                rulesetContainer,
                                layerAboveRuleset
                            }
                        }
                    },
                },
                ColumnDimensions = new[]
                {
                    new Dimension(GridSizeMode.Absolute, 200),
                }
            };

            toolboxCollection.Items =
                CompositionTools.Select(t => new RadioButton(t.Name, () => setCompositionTool(t)))
                .Prepend(new RadioButton("Select", () => setCompositionTool(null)))
                .ToList();

            toolboxCollection.Items[0].Select();
        }
예제 #11
0
 public InvadersScoreProcessor(RulesetContainer <InvadersHitObject> rulesetContainer) : base(rulesetContainer)
 {
 }
예제 #12
0
파일: ReplayPlayer.cs 프로젝트: yazici/osu
 protected override void LoadComplete()
 {
     base.LoadComplete();
     RulesetContainer?.SetReplayScore(score);
 }
예제 #13
0
 public RpScoreProcessor(RulesetContainer <BaseRpObject> hitRenderer)
     : base(hitRenderer)
 {
 }
예제 #14
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     RulesetContainer.SetReplay(score.Replay);
 }
예제 #15
0
 public CatchScoreProcessor(RulesetContainer <CatchBaseHit, CatchJudgement> rulesetContainer)
     : base(rulesetContainer)
 {
 }
예제 #16
0
파일: Player.cs 프로젝트: miterosan/osu
        private void load(AudioManager audio, OsuConfigManager config, APIAccess api)
        {
            this.api = api;

            dimLevel       = config.GetBindable <double>(OsuSetting.DimLevel);
            showStoryboard = config.GetBindable <bool>(OsuSetting.ShowStoryboard);

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

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

            WorkingBeatmap working = Beatmap.Value;
            Beatmap        beatmap;

            try
            {
                beatmap = working.Beatmap;

                if (beatmap == null)
                {
                    throw new InvalidOperationException("Beatmap was not loaded");
                }

                ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset;
                var rulesetInstance = ruleset.CreateInstance();

                try
                {
                    RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working, ruleset.ID == beatmap.BeatmapInfo.Ruleset.ID);
                }
                catch (BeatmapInvalidForRulesetException)
                {
                    // we may fail to create a RulesetContainer if the beatmap cannot be loaded with the user's preferred ruleset
                    // let's try again forcing the beatmap's ruleset.
                    ruleset          = beatmap.BeatmapInfo.Ruleset;
                    rulesetInstance  = ruleset.CreateInstance();
                    RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap, true);
                }

                if (!RulesetContainer.Objects.Any())
                {
                    throw new InvalidOperationException("Beatmap contains no hit objects!");
                }
            }
            catch (Exception e)
            {
                Logger.Log($"Could not load this beatmap sucessfully ({e})!", LoggingTarget.Runtime, LogLevel.Error);

                //couldn't load, hard abort!
                Exit();
                return;
            }

            adjustableSourceClock = (IAdjustableClock)working.Track ?? new StopwatchClock();
            decoupledClock        = new DecoupleableInterpolatingFramedClock {
                IsCoupled = false
            };

            var firstObjectTime = RulesetContainer.Objects.First().StartTime;

            decoupledClock.Seek(Math.Min(0, firstObjectTime - Math.Max(beatmap.ControlPointInfo.TimingPointAt(firstObjectTime).BeatLength * 4, beatmap.BeatmapInfo.AudioLeadIn)));
            decoupledClock.ProcessFrame();

            offsetClock = new FramedOffsetClock(decoupledClock);

            userAudioOffset = config.GetBindable <double>(OsuSetting.AudioOffset);
            userAudioOffset.ValueChanged += v => offsetClock.Offset = v;
            userAudioOffset.TriggerChange();

            Schedule(() =>
            {
                adjustableSourceClock.Reset();

                foreach (var mod in working.Mods.Value.OfType <IApplicableToClock>())
                {
                    mod.ApplyToClock(adjustableSourceClock);
                }

                decoupledClock.ChangeSource(adjustableSourceClock);
            });

            Children = new Drawable[]
            {
                storyboardContainer = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                    Clock            = offsetClock,
                    Alpha            = 0,
                },
                pauseContainer = new PauseContainer
                {
                    AudioClock    = decoupledClock,
                    FramedClock   = offsetClock,
                    OnRetry       = Restart,
                    OnQuit        = Exit,
                    CheckCanPause = () => ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded,
                    Retries       = RestartCount,
                    OnPause       = () => {
                        hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused;
                    },
                    OnResume = () => {
                        hudOverlay.KeyCounter.IsCounting = true;
                    },
                    Children = new Drawable[]
                    {
                        new SkipButton(firstObjectTime)
                        {
                            AudioClock = decoupledClock
                        },
                        new Container
                        {
                            RelativeSizeAxes = Axes.Both,
                            Clock            = offsetClock,
                            Child            = RulesetContainer,
                        },
                        hudOverlay = new HUDOverlay
                        {
                            Anchor = Anchor.Centre,
                            Origin = Anchor.Centre
                        },
                        breakOverlay = new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks)
                        {
                            Anchor = Anchor.Centre,
                            Origin = Anchor.Centre,
                            Clock  = decoupledClock,
                            Breaks = beatmap.Breaks
                        },
                    }
                },
                failOverlay = new FailOverlay
                {
                    OnRetry = Restart,
                    OnQuit  = Exit,
                },
                new HotkeyRetryOverlay
                {
                    Action = () => {
                        //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();
                        Restart();
                    },
                }
            };

            scoreProcessor = RulesetContainer.CreateScoreProcessor();

            if (showStoryboard)
            {
                initializeStoryboard(false);
            }

            hudOverlay.BindProcessor(scoreProcessor);
            hudOverlay.BindRulesetContainer(RulesetContainer);

            hudOverlay.Progress.Objects      = RulesetContainer.Objects;
            hudOverlay.Progress.AudioClock   = decoupledClock;
            hudOverlay.Progress.AllowSeeking = RulesetContainer.HasReplayLoaded;
            hudOverlay.Progress.OnSeek       = pos => decoupledClock.Seek(pos);

            hudOverlay.ModDisplay.Current.BindTo(working.Mods);

            breakOverlay.BindProcessor(scoreProcessor);

            // Bind ScoreProcessor to ourselves
            scoreProcessor.AllJudged += onCompletion;
            scoreProcessor.Failed    += onFail;
        }
예제 #17
0
 public void ApplyToRulesetContainer(RulesetContainer <T> rulesetContainer)
 {
     rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay);
 }
예제 #18
0
 public ManiaScoreProcessor(RulesetContainer <ManiaHitObject> rulesetContainer)
     : base(rulesetContainer)
 {
 }
예제 #19
0
        public void ApplyToRulesetContainer(RulesetContainer <ManiaHitObject> rulesetContainer)
        {
            var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;

            rulesetContainer.Objects.OfType <ManiaHitObject>().ForEach(h => h.Column = availableColumns - 1 - h.Column);
        }
예제 #20
0
 public CatchScoreProcessor(RulesetContainer <CatchHitObject> rulesetContainer)
     : base(rulesetContainer)
 {
 }
예제 #21
0
 public override void ApplyToRulesetContainer(RulesetContainer <TaikoHitObject> rulesetContainer)
 {
     playfield = (TaikoPlayfield)rulesetContainer.Playfield;
     base.ApplyToRulesetContainer(rulesetContainer);
 }
예제 #22
0
 public virtual void ApplyToRulesetContainer(RulesetContainer <T> rulesetContainer) => rulesetContainer.SetReplayScore(CreateReplayScore(rulesetContainer.Beatmap));
 public CytusScoreProcessor(RulesetContainer <CytusHitObject> rulesetContainer) : base(rulesetContainer)
 {
 }
예제 #24
0
        private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
        {
            this.api = api;

            WorkingBeatmap working = Beatmap.Value;

            if (working is DummyWorkingBeatmap)
            {
                return;
            }

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

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

            IBeatmap beatmap;

            try
            {
                beatmap = working.Beatmap;

                if (beatmap == null)
                {
                    throw new InvalidOperationException("Beatmap was not loaded");
                }

                ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset;
                var rulesetInstance = ruleset.CreateInstance();

                try
                {
                    RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working);
                }
                catch (BeatmapInvalidForRulesetException)
                {
                    // we may fail to create a RulesetContainer if the beatmap cannot be loaded with the user's preferred ruleset
                    // let's try again forcing the beatmap's ruleset.
                    ruleset          = beatmap.BeatmapInfo.Ruleset;
                    rulesetInstance  = ruleset.CreateInstance();
                    RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap.Value);
                }

                if (!RulesetContainer.Objects.Any())
                {
                    Logger.Error(new InvalidOperationException("Beatmap contains no hit objects!"), "Beatmap contains no hit objects!");
                    return;
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "Could not load beatmap sucessfully!");
                //couldn't load, hard abort!
                return;
            }

            sourceClock     = (IAdjustableClock)working.Track ?? new StopwatchClock();
            adjustableClock = new DecoupleableInterpolatingFramedClock {
                IsCoupled = false
            };

            adjustableClock.Seek(AllowLeadIn
                ? Math.Min(RulesetContainer.GameplayStartTime, beatmap.HitObjects.First().StartTime - beatmap.BeatmapInfo.AudioLeadIn)
                : RulesetContainer.GameplayStartTime);

            adjustableClock.ProcessFrame();

            // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited.
            // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck.
            var platformOffsetClock = new FramedOffsetClock(adjustableClock)
            {
                Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0
            };

            // the final usable gameplay clock with user-set offsets applied.
            var offsetClock = new FramedOffsetClock(platformOffsetClock);

            userAudioOffset.ValueChanged += v => offsetClock.Offset = v;
            userAudioOffset.TriggerChange();

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

            Children = new Drawable[]
            {
                pauseContainer = new PauseContainer(offsetClock, adjustableClock)
                {
                    Retries       = RestartCount,
                    OnRetry       = Restart,
                    OnQuit        = Exit,
                    CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded,
                    Children      = new[]
                    {
                        storyboardContainer = new Container
                        {
                            RelativeSizeAxes = Axes.Both,
                            Alpha            = 0,
                        },
                        new LocalSkinOverrideContainer(working.Skin)
                        {
                            RelativeSizeAxes = Axes.Both,
                            Child            = RulesetContainer
                        },
                        new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
                        {
                            Anchor             = Anchor.Centre,
                            Origin             = Anchor.Centre,
                            ProcessCustomClock = false,
                            Breaks             = beatmap.Breaks
                        },
                        RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
                        hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
                        {
                            Clock = Clock, // hud overlay doesn't want to use the audio clock directly
                            ProcessCustomClock = false,
                            Anchor             = Anchor.Centre,
                            Origin             = Anchor.Centre
                        },
                        new SkipOverlay(RulesetContainer.GameplayStartTime)
                        {
                            Clock = Clock, // skip button doesn't want to use the audio clock directly
                            ProcessCustomClock = false,
                            AdjustableClock    = adjustableClock,
                            FramedClock        = offsetClock,
                        },
                    }
                },
                failOverlay = new FailOverlay
                {
                    OnRetry = Restart,
                    OnQuit  = Exit,
                },
                new HotkeyRetryOverlay
                {
                    Action = () =>
                    {
                        if (!IsCurrentScreen)
                        {
                            return;
                        }

                        pauseContainer.Hide();
                        Restart();
                    },
                }
            };

            hudOverlay.HoldToQuit.Action = Exit;
            hudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded);

            RulesetContainer.IsPaused.BindTo(pauseContainer.IsPaused);

            if (ShowStoryboard)
            {
                initializeStoryboard(false);
            }

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

            foreach (var mod in Beatmap.Value.Mods.Value.OfType <IApplicableToScoreProcessor>())
            {
                mod.ApplyToScoreProcessor(ScoreProcessor);
            }
        }
예제 #25
0
파일: OsuModRelax.cs 프로젝트: vbe0201/osu
 public void ApplyToRulesetContainer(RulesetContainer <OsuHitObject> rulesetContainer)
 {
     // grab the input manager for future use.
     osuInputManager = (OsuInputManager)rulesetContainer.KeyBindingInputManager;
     osuInputManager.AllowUserPresses = false;
 }
예제 #26
0
파일: Player.cs 프로젝트: changeGithub/osu
        private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
        {
            this.api = api;

            WorkingBeatmap working = Beatmap.Value;

            if (working is DummyWorkingBeatmap)
            {
                return;
            }

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

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

            IBeatmap beatmap;

            try
            {
                beatmap = working.Beatmap;

                if (beatmap == null)
                {
                    throw new InvalidOperationException("Beatmap was not loaded");
                }

                ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset;
                var rulesetInstance = ruleset.CreateInstance();

                try
                {
                    RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working);
                }
                catch (BeatmapInvalidForRulesetException)
                {
                    // we may fail to create a RulesetContainer if the beatmap cannot be loaded with the user's preferred ruleset
                    // let's try again forcing the beatmap's ruleset.
                    ruleset          = beatmap.BeatmapInfo.Ruleset;
                    rulesetInstance  = ruleset.CreateInstance();
                    RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap);
                }

                if (!RulesetContainer.Objects.Any())
                {
                    Logger.Error(new InvalidOperationException("Beatmap contains no hit objects!"), "Beatmap contains no hit objects!");
                    return;
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "Could not load beatmap sucessfully!");
                //couldn't load, hard abort!
                return;
            }

            sourceClock     = (IAdjustableClock)working.Track ?? new StopwatchClock();
            adjustableClock = new DecoupleableInterpolatingFramedClock {
                IsCoupled = false
            };

            var firstObjectTime = RulesetContainer.Objects.First().StartTime;

            adjustableClock.Seek(AllowLeadIn
                ? Math.Min(0, firstObjectTime - Math.Max(beatmap.ControlPointInfo.TimingPointAt(firstObjectTime).BeatLength * 4, beatmap.BeatmapInfo.AudioLeadIn))
                : firstObjectTime);

            adjustableClock.ProcessFrame();

            // the final usable gameplay clock with user-set offsets applied.
            var offsetClock = new FramedOffsetClock(adjustableClock);

            userAudioOffset.ValueChanged += v => offsetClock.Offset = v;
            userAudioOffset.TriggerChange();

            ScoreProcessor = RulesetContainer.CreateScoreProcessor();

            Children = new Drawable[]
            {
                pauseContainer = new PauseContainer(offsetClock, adjustableClock)
                {
                    OnRetry       = Restart,
                    OnQuit        = Exit,
                    CheckCanPause = () => AllowPause && ValidForResume && !HasFailed && !RulesetContainer.HasReplayLoaded,
                    OnPause       = () =>
                    {
                        pauseContainer.Retries           = RestartCount;
                        hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused;
                    },
                    OnResume = () => hudOverlay.KeyCounter.IsCounting = true,
                    Children = new[]
                    {
                        storyboardContainer = new Container
                        {
                            RelativeSizeAxes = Axes.Both,
                            Alpha            = 0,
                        },
                        new LocalSkinOverrideContainer(working.Skin)
                        {
                            RelativeSizeAxes = Axes.Both,
                            Child            = RulesetContainer
                        },
                        new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
                        {
                            Anchor             = Anchor.Centre,
                            Origin             = Anchor.Centre,
                            ProcessCustomClock = false,
                            Breaks             = beatmap.Breaks
                        },
                        RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
                        hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
                        {
                            Clock = Clock, // hud overlay doesn't want to use the audio clock directly
                            ProcessCustomClock = false,
                            Anchor             = Anchor.Centre,
                            Origin             = Anchor.Centre
                        },
                        new SkipOverlay(firstObjectTime)
                        {
                            Clock = Clock, // skip button doesn't want to use the audio clock directly
                            ProcessCustomClock = false,
                            AdjustableClock    = adjustableClock,
                            FramedClock        = offsetClock,
                        },
                    }
                },
                failOverlay = new FailOverlay
                {
                    OnRetry = Restart,
                    OnQuit  = Exit,
                },
                new HotkeyRetryOverlay
                {
                    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();
                        Restart();
                    },
                }
            };

            hudOverlay.HoldToQuit.Action = Exit;

            if (ShowStoryboard)
            {
                initializeStoryboard(false);
            }

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

            foreach (var mod in Beatmap.Value.Mods.Value.OfType <IApplicableToScoreProcessor>())
            {
                mod.ApplyToScoreProcessor(ScoreProcessor);
            }
        }
예제 #27
0
        private void load([NotNull] OsuGameBase osuGame, [NotNull] IAdjustableClock adjustableClock, [NotNull] IFrameBasedClock framedClock, [CanBeNull] BindableBeatDivisor beatDivisor)
        {
            this.adjustableClock = adjustableClock;

            if (beatDivisor != null)
            {
                this.beatDivisor.BindTo(beatDivisor);
            }

            beatmap.BindTo(osuGame.Beatmap);

            try
            {
                rulesetContainer       = CreateRulesetContainer(ruleset, beatmap.Value);
                rulesetContainer.Clock = framedClock;
            }
            catch (Exception e)
            {
                Logger.Error(e, "Could not load beatmap sucessfully!");
                return;
            }

            HitObjectMaskLayer hitObjectMaskLayer = new HitObjectMaskLayer(this);
            SelectionLayer     selectionLayer     = new SelectionLayer(rulesetContainer.Playfield);

            var layerBelowRuleset = new BorderLayer
            {
                RelativeSizeAxes = Axes.Both,
                Child            = CreateLayerContainer()
            };

            var layerAboveRuleset = CreateLayerContainer();

            layerAboveRuleset.Children = new Drawable[]
            {
                selectionLayer,              // Below object overlays for input
                hitObjectMaskLayer,
                selectionLayer.CreateProxy() // Proxy above object overlays for selections
            };

            layerContainers.Add(layerBelowRuleset);
            layerContainers.Add(layerAboveRuleset);

            RadioButtonCollection toolboxCollection;

            InternalChild = new GridContainer
            {
                RelativeSizeAxes = Axes.Both,
                Content          = new[]
                {
                    new Drawable[]
                    {
                        new FillFlowContainer
                        {
                            Name             = "Sidebar",
                            RelativeSizeAxes = Axes.Both,
                            Padding          = new MarginPadding {
                                Right = 10
                            },
                            Children = new Drawable[]
                            {
                                new ToolboxGroup {
                                    Child = toolboxCollection = new RadioButtonCollection {
                                        RelativeSizeAxes = Axes.X
                                    }
                                }
                            }
                        },
                        new Container
                        {
                            Name             = "Content",
                            RelativeSizeAxes = Axes.Both,
                            Children         = new Drawable[]
                            {
                                layerBelowRuleset,
                                rulesetContainer,
                                layerAboveRuleset
                            }
                        }
                    },
                },
                ColumnDimensions = new[]
                {
                    new Dimension(GridSizeMode.Absolute, 200),
                }
            };

            selectionLayer.ObjectSelected    += hitObjectMaskLayer.AddOverlay;
            selectionLayer.ObjectDeselected  += hitObjectMaskLayer.RemoveOverlay;
            selectionLayer.SelectionCleared  += hitObjectMaskLayer.RemoveSelectionOverlay;
            selectionLayer.SelectionFinished += hitObjectMaskLayer.AddSelectionOverlay;

            toolboxCollection.Items =
                new[] { new RadioButton("Select", () => setCompositionTool(null)) }
            .Concat(
                CompositionTools.Select(t => new RadioButton(t.Name, () => setCompositionTool(t)))
                )
            .ToList();

            toolboxCollection.Items[0].Select();
        }