private void addGameplayComponents(Container target, WorkingBeatmap working) { var beatmapSkinProvider = new BeatmapSkinProvidingContainer(working.Skin); // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation // full access to all skin sources. var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider)); // 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. target.Add(new ScalingContainer(ScalingMode.Gameplay) .WithChild(beatmapSkinProvider .WithChild(target = rulesetSkinProvider))); target.AddRange(new Drawable[] { DrawableRuleset, new ComboEffects(ScoreProcessor) }); DrawableRuleset.FrameStableComponents.AddRange(new Drawable[] { ScoreProcessor, HealthProcessor, breakTracker = new BreakTracker(DrawableRuleset.GameplayStartTime, ScoreProcessor) { Breaks = working.Beatmap.Breaks } }); HealthProcessor.IsBreakTime.BindTo(breakTracker.IsBreakTime); }
public void TestSamplePlaybackWithBeatmapHitsoundsOff() { GameplayClockContainer gameplayContainer = null; TestDrawableStoryboardSample sample = null; AddStep("disable beatmap hitsounds", () => config.SetValue(OsuSetting.BeatmapHitsounds, false)); AddStep("setup storyboard sample", () => { Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, this); var beatmapSkinSourceContainer = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin); Add(gameplayContainer = new MasterGameplayClockContainer(Beatmap.Value, 0) { Child = beatmapSkinSourceContainer }); beatmapSkinSourceContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { Clock = gameplayContainer.GameplayClock }); }); AddStep("start", () => gameplayContainer.Start()); AddUntilStep("sample played", () => sample.IsPlayed); AddUntilStep("sample has lifetime end", () => sample.LifetimeEnd < double.MaxValue); AddStep("restore default", () => config.GetBindable <bool>(OsuSetting.BeatmapHitsounds).SetDefault()); }
private Drawable wrapSkinnableContent(Drawable content) { Debug.Assert(ruleset != null); var beatmapSkinProvider = new BeatmapSkinProvidingContainer(beatmap.Value.Skin); // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation // full access to all skin sources. var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, EditorBeatmap.PlayableBeatmap)); // 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. return(beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(content))); }
protected override Drawable CreateMainContent() { if (ruleset == null || composer == null) { return(new ScreenWhiteBox.UnderConstructionMessage(ruleset == null ? "This beatmap" : $"{ruleset.Description}'s composer")); } var beatmapSkinProvider = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin); // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation // full access to all skin sources. var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, EditorBeatmap.PlayableBeatmap)); // 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. return(beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(composer))); }
public void TestSamplePlaybackWithRateMods(Type expectedMod, double expectedRate) { GameplayClockContainer gameplayContainer = null; StoryboardSampleInfo sampleInfo = null; TestDrawableStoryboardSample sample = null; Mod testedMod = Activator.CreateInstance(expectedMod) as Mod; switch (testedMod) { case ModRateAdjust m: m.SpeedChange.Value = expectedRate; break; case ModTimeRamp m: m.FinalRate.Value = m.InitialRate.Value = expectedRate; break; } AddStep("setup storyboard sample", () => { Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, this); SelectedMods.Value = new[] { testedMod }; var beatmapSkinSourceContainer = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin); Add(gameplayContainer = new MasterGameplayClockContainer(Beatmap.Value, 0) { Child = beatmapSkinSourceContainer }); beatmapSkinSourceContainer.Add(sample = new TestDrawableStoryboardSample(sampleInfo = new StoryboardSampleInfo("test-sample", 1, 1)) { Clock = gameplayContainer.GameplayClock }); }); AddStep("start", () => gameplayContainer.Start()); AddAssert("sample playback rate matches mod rates", () => testedMod != null && Precision.AlmostEquals( sample.ChildrenOfType <DrawableSample>().First().AggregateFrequency.Value, ((IApplicableToRate)testedMod).ApplyToRate(sampleInfo.StartTime))); }
private void load(AudioManager audio, OsuConfigManager config, OsuGame game) { Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); if (Beatmap.Value is DummyWorkingBeatmap) { return; } IBeatmap playableBeatmap = loadPlayableBeatmap(); if (playableBeatmap == null) { return; } sampleRestart = audio.Samples.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableWheel); if (game != null) { LocalUserPlaying.BindTo(game.LocalUserPlaying); } DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value); ScoreProcessor = ruleset.CreateScoreProcessor(); ScoreProcessor.ApplyBeatmap(playableBeatmap); ScoreProcessor.Mods.BindTo(Mods); HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor.ApplyBeatmap(playableBeatmap); if (!ScoreProcessor.Mode.Disabled) { config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); } InternalChild = GameplayClockContainer = CreateGameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime); AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer)); dependencies.CacheAs(gameplayBeatmap); var beatmapSkinProvider = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin); // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation // full access to all skin sources. var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap)); // 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(beatmapSkinProvider.WithChild(rulesetSkinProvider)); rulesetSkinProvider.AddRange(new[] { // underlay and gameplay should have access the to skinning sources. createUnderlayComponents(), createGameplayComponents(Beatmap.Value, playableBeatmap) }); // also give the HUD a ruleset container 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. var hudRulesetContainer = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap)); // add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components. GameplayClockContainer.Add(hudRulesetContainer.WithChild(createOverlayComponents(Beatmap.Value))); if (!DrawableRuleset.AllowGameplayOverlays) { HUDOverlay.ShowHud.Value = false; HUDOverlay.ShowHud.Disabled = true; BreakOverlay.Hide(); skipOverlay.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()); DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); DrawableRuleset.NewResult += r => { HealthProcessor.ApplyResult(r); ScoreProcessor.ApplyResult(r); gameplayBeatmap.ApplyResult(r); }; DrawableRuleset.RevertResult += r => { HealthProcessor.RevertResult(r); ScoreProcessor.RevertResult(r); }; // Bind the judgement processors to ourselves ScoreProcessor.HasCompleted.ValueChanged += updateCompletionState; HealthProcessor.Failed += onFail; foreach (var mod in Mods.Value.OfType <IApplicableToScoreProcessor>()) { mod.ApplyToScoreProcessor(ScoreProcessor); } foreach (var mod in Mods.Value.OfType <IApplicableToHealthProcessor>()) { mod.ApplyToHealthProcessor(HealthProcessor); } IsBreakTime.BindTo(breakTracker.IsBreakTime); IsBreakTime.BindValueChanged(onBreakTimeChanged, true); }