Пример #1
0
        private void bindBeatmap()
        {
            if (beatmap == null)
                beatmap = new Bindable<WorkingBeatmap>();

            if (!boundToBeatmap)
            {
                beatmap.ValueChanged += beatmap_ValueChanged;
                boundToBeatmap = true;
            }
        }
Пример #2
0
        public void InitTest()
        {
            var str = "Hello World!";
            Bindable<int> bindable;
            {
                var number = 10;
                bindable = new Bindable<int>(() => number, value => number = value);
                number++;
            }

            str = "Not hello!";
        }
        public void BindableTest()
        {
            bool triggered = false;
            var bindable = new Bindable();
            bindable.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == "Foo")
                {
                    triggered = true;
                }
            };

            bindable.Foo = 42;
            Assert.IsTrue(triggered);
        }
Пример #4
0
        private void load()
        {
            if (!Host.IsPrimaryInstance)
            {
                Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error);
                Environment.Exit(0);
            }

            if (args?.Length > 0)
                Schedule(delegate { Dependencies.Get<BeatmapDatabase>().Import(args); });

            Dependencies.Cache(this);

            //attach our bindables to the audio subsystem.
            Audio.Volume.Weld(Config.GetBindable<double>(OsuConfig.VolumeUniversal));
            Audio.VolumeSample.Weld(Config.GetBindable<double>(OsuConfig.VolumeEffect));
            Audio.VolumeTrack.Weld(Config.GetBindable<double>(OsuConfig.VolumeMusic));

            PlayMode = Config.GetBindable<PlayMode>(OsuConfig.PlayMode);
        }
Пример #5
0
        private void load(OsuConfigManager config)
        {
            this.config = config;

            preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
            preferUnicode.ValueChanged += preferUnicode_changed;
            preferUnicode_changed(preferUnicode, null);
        }
Пример #6
0
        private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config, OsuGame osu)
        {
            dimLevel           = config.GetBindable <double>(OsuSetting.DimLevel);
            mouseWheelDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableWheel);

            Ruleset rulesetInstance;

            try
            {
                if (Beatmap == null)
                {
                    Beatmap = beatmaps.GetWorkingBeatmap(BeatmapInfo, withStoryboard: true);
                }

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

                ruleset         = osu?.Ruleset.Value ?? Beatmap.BeatmapInfo.Ruleset;
                rulesetInstance = ruleset.CreateInstance();

                try
                {
                    HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap, ruleset.ID == Beatmap.BeatmapInfo.Ruleset.ID);
                }
                catch (BeatmapInvalidForRulesetException)
                {
                    // we may fail to create a HitRenderer 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();
                    HitRenderer     = rulesetInstance.CreateHitRendererWith(Beatmap, true);
                }

                if (!HitRenderer.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;
            }

            Track track = Beatmap.Track;

            if (track != null)
            {
                audio.Track.SetExclusive(track);
                adjustableSourceClock = track;
            }

            adjustableSourceClock = (IAdjustableClock)track ?? new StopwatchClock();

            decoupledClock = new DecoupleableInterpolatingFramedClock {
                IsCoupled = false
            };

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

            decoupledClock.Seek(Math.Min(0, firstObjectTime - Math.Max(Beatmap.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 Beatmap.Mods.Value.OfType <IApplicableToClock>())
                {
                    mod.ApplyToClock(adjustableSourceClock);
                }

                decoupledClock.ChangeSource(adjustableSourceClock);
            });

            Children = new Drawable[]
            {
                pauseContainer = new PauseContainer
                {
                    AudioClock    = decoupledClock,
                    FramedClock   = offsetClock,
                    OnRetry       = Restart,
                    OnQuit        = Exit,
                    CheckCanPause = () => ValidForResume && !HasFailed && !HitRenderer.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,
                            Children         = new Drawable[]
                            {
                                HitRenderer,
                            }
                        },
                        hudOverlay = new StandardHUDOverlay
                        {
                            Anchor = Anchor.Centre,
                            Origin = Anchor.Centre
                        },
                    }
                },
                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.
                        HitRenderer?.Hide();
                        Restart();
                    },
                }
            };

            scoreProcessor = HitRenderer.CreateScoreProcessor();

            hudOverlay.KeyCounter.Add(rulesetInstance.CreateGameplayKeys());
            hudOverlay.BindProcessor(scoreProcessor);
            hudOverlay.BindHitRenderer(HitRenderer);

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

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

            //bind HitRenderer to ScoreProcessor and ourselves (for a pass situation)
            HitRenderer.OnAllJudged += onCompletion;

            //bind ScoreProcessor to ourselves (for a fail situation)
            scoreProcessor.Failed += onFail;
        }
Пример #7
0
        private void load(OsuConfigManager config)
        {
            snakingIn = config.GetBindable<bool>(OsuConfig.SnakingInSliders);
            snakingOut = config.GetBindable<bool>(OsuConfig.SnakingOutSliders);

            int textureWidth = (int)PathWidth * 2;

            //initialise background
            var upload = new TextureUpload(textureWidth * 4);
            var bytes = upload.Data;

            const float aa_portion = 0.02f;
            const float border_portion = 0.18f;
            const float gradient_portion = 1 - border_portion;

            const float opacity_at_centre = 0.3f;
            const float opacity_at_edge = 0.8f;

            for (int i = 0; i < textureWidth; i++)
            {
                float progress = (float)i / (textureWidth - 1);

                if (progress <= border_portion)
                {
                    bytes[i * 4] = 255;
                    bytes[i * 4 + 1] = 255;
                    bytes[i * 4 + 2] = 255;
                    bytes[i * 4 + 3] = (byte)(Math.Min(progress / aa_portion, 1) * 255);
                }
                else
                {
                    progress -= border_portion;

                    bytes[i * 4] = (byte)(slider.Colour.R * 255);
                    bytes[i * 4 + 1] = (byte)(slider.Colour.G * 255);
                    bytes[i * 4 + 2] = (byte)(slider.Colour.B * 255);
                    bytes[i * 4 + 3] = (byte)((opacity_at_edge - (opacity_at_edge - opacity_at_centre) * progress / gradient_portion) * (slider.Colour.A * 255));
                }
            }

            var texture = new Texture(textureWidth, 1);
            texture.SetData(upload);
            path.Texture = texture;
        }
Пример #8
0
        public override void Load()
        {
            // Load movedb

            BaseMove.LoadMoveDb();

            // Initalize Discord RP on Mod Load
            if (!Main.dedServ)
            {
                client        = new DiscordRpcClient("790364236554829824");
                client.Logger = new ConsoleLogger()
                {
                    Level = LogLevel.Warning
                };
                //

                Logger.Info("Attempting to establish Discord RP connection");

                // Subscribe to events
                client.OnReady += (sender, e) =>
                {
                    Logger.Info("Established connection");
                    Console.WriteLine("Received Ready from user {0}", e.User.Username);
                };

                client.OnPresenceUpdate += (sender, e) =>
                {
                    Console.WriteLine("Received Update! {0}", e.Presence);
                };

                client.OnError += (sender, e) =>
                {
                    Logger.Error("Could not start Discord RP. Reason: " + e.Message);
                };

                //Connect to the RPC
                client.Initialize();

                client.SetPresence(new RichPresence()
                {
                    Details = "In Menu",
                    State   = "Playing v0.4.2",
                    Assets  = new Assets()
                    {
                        LargeImageKey  = "largeimage2",
                        LargeImageText = "Merry Christmas!"
                    }
                });
            }

            BaseMove._mrand = new UnifiedRandom(BaseMove._seed = new Random().Next());
            //Load all mons to a store
            LoadPokemons();

            if (Main.netMode != NetmodeID.Server)
            {
                if (Localisation == null)
                {
                    Localisation = new LocalisationManager(locale);
                }
                locale = new Bindable <string>(Language.ActiveCulture.Name);

                storage = new ModStorage("Terramon");                                                                  //Initialise local resource store
                Store   = new ResourceStore <byte[]>(new EmbeddedStore());                                             //Make new instance of ResourceStore with dependency what loads data from ModStore
                Store.AddStore(new StorageCachableStore(storage, new WebStore()));                                     //Add second dependency what checks if data exist in local store.
                                                                                                                       //If not and provided URL load data from web and save it on drive
                Textures = new Texture2DStore(Store);                                                                  //Initialise cachable texture store in order not creating new texture each call

                Localisation.AddLanguage(GameCulture.English.Name, new LocalisationStore(Store, GameCulture.English)); //Adds en-US.lang file handling
                Localisation.AddLanguage(GameCulture.Russian.Name, new LocalisationStore(Store, GameCulture.Russian)); //Adds ru-RU.lang file handling
#if DEBUG
                UseWebAssets = true;
                var ss = Localisation.GetLocalisedString(new LocalisedString(("title", "Powered by broken code")));//It's terrible checking in ui from phone, so i can ensure everything works from version string
                //Main.versionNumber = ss.Value + "\n" + Main.versionNumber;
#endif
                Ref <Effect> screenRef = new Ref <Effect>(GetEffect("Effects/ShockwaveEffect")); // The path to the compiled shader file.
                Filters.Scene["Shockwave"] = new Filter(new ScreenShaderData(screenRef, "Shockwave"), EffectPriority.VeryHigh);
                Filters.Scene["Shockwave"].Load();

                ChooseStarter = new ChooseStarter();
                ChooseStarter.Activate();
                ChooseStarterBulbasaur = new ChooseStarterBulbasaur();
                ChooseStarterBulbasaur.Activate();
                ChooseStarterCharmander = new ChooseStarterCharmander();
                ChooseStarterCharmander.Activate();
                ChooseStarterSquirtle = new ChooseStarterSquirtle();
                ChooseStarterSquirtle.Activate();
                PokegearUI = new PokegearUI();
                PokegearUI.Activate();
                PokegearUIEvents = new PokegearUIEvents();
                PokegearUIEvents.Activate();
                evolveUI = new EvolveUI();
                evolveUI.Activate();
                UISidebar = new UISidebar();
                UISidebar.Activate();
                Moves = new Moves();
                Moves.Activate();
                PartySlots = new PartySlots();
                PartySlots.Activate();
                _exampleUserInterface    = new UserInterface();
                _exampleUserInterfaceNew = new UserInterface();
                PokegearUserInterfaceNew = new UserInterface();
                evolveUserInterfaceNew   = new UserInterface();
                _uiSidebar  = new UserInterface();
                _moves      = new UserInterface();
                _partySlots = new UserInterface();
                _battle     = new UserInterface();
                ParentPokemonNPC.HighlightTexture = new Dictionary <string, Texture2D>();
                ParentPokemon.HighlightTexture    = new Dictionary <string, Texture2D>();

                //_exampleUserInterface.SetState(ChooseStarter); // Choose Starter
#if DEBUG
                _exampleUserInterface.SetState(new TestState());
#endif
                _exampleUserInterfaceNew.SetState(PokegearUI);       // Pokegear Main Menu
                PokegearUserInterfaceNew.SetState(PokegearUIEvents); // Pokegear Events Menu
                evolveUserInterfaceNew.SetState(evolveUI);
                _uiSidebar.SetState(UISidebar);
                _moves.SetState(Moves);
                _partySlots.SetState(PartySlots);
                _battle.SetState(BattleMode.UI = new BattleUI());// Automatically assign shortcut

                summaryUI = new AnimatorUI();
                summaryUI.Activate();

                summaryUIInterface = new UserInterface();
                summaryUIInterface.SetState(summaryUI);
            }


            if (Main.dedServ)
            {
                return;
            }

            Scheduler = new Scheduler(Thread.CurrentThread, schedulerClock = new GameTimeClock());

            FirstPKMAbility  = RegisterHotKey("First Pokémon Move", Keys.Z.ToString());
            SecondPKMAbility = RegisterHotKey("Second Pokémon Move", Keys.X.ToString());
            ThirdPKMAbility  = RegisterHotKey("Third Pokémon Move", Keys.C.ToString());
            FourthPKMAbility = RegisterHotKey("Fourth Pokémon Move", Keys.V.ToString());

            CompressSidebar = RegisterHotKey("Compress Sidebar", Keys.RightShift.ToString());

            PartyCycle = RegisterHotKey("Quick Spawn First Party Pokémon", Keys.RightAlt.ToString());
        }
Пример #9
0
 internal IndexTitleDescriptionChevron(Bindable <string> indexBinding, Bindable <string> titleBinding, Bindable <string> descriptionBinding, Bindable <string> chevronBinding)
 {
     Title.Bind("Text", () => titleBinding);
     Description.Bind("Text", () => descriptionBinding);
     Index.Bind("Text", () => indexBinding);
     Chevron.Bind("Text", () => chevronBinding);
 }
Пример #10
0
 public void ReadFromConfig(OsuConfigManager config)
 {
     increaseFirstObjectVisibility = config.GetBindable <bool>(OsuSetting.IncreaseFirstObjectVisibility);
 }
Пример #11
0
        private void load(GameHost host)
        {
            listener = new DotNetRuntimeListener();

            performanceLogging = host.PerformanceLogging.GetBoundCopy();
        }
Пример #12
0
 private void load(OsuConfigManager config)
 {
     mouseDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableButtons);
 }
 /// <summary>
 /// Smoothly adjusts the value of a <see cref="Bindable{TValue}"/> over time.
 /// </summary>
 /// <returns>A <see cref="TransformSequence{T}"/> to which further transforms can be added.</returns>
 public static TransformSequence <T> TransformBindableTo <T, TValue>(this TransformSequence <T> t, [NotNull] Bindable <TValue> bindable, TValue newValue, double duration = 0, Easing easing = Easing.None,
                                                                     InterpolationFunc <TValue> interpolationFunc = null)
     where T : ITransformable =>
 t.Append(o => o.TransformBindableTo(bindable, newValue, duration, easing, interpolationFunc));
Пример #14
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);
        }
Пример #15
0
            public DisplayStyleToggleButton(FontAwesome icon, PanelDisplayStyle style, Bindable <PanelDisplayStyle> bindable)
            {
                this.bindable = bindable;
                this.style    = style;
                Size          = new Vector2(25f);

                Children = new Drawable[]
                {
                    this.icon = new SpriteIcon
                    {
                        Anchor = Anchor.Centre,
                        Origin = Anchor.Centre,
                        Icon   = icon,
                        Size   = new Vector2(18),
                        Alpha  = 0.5f,
                    },
                };

                bindable.ValueChanged += Bindable_ValueChanged;
                Bindable_ValueChanged(bindable.Value);
                Action = () => bindable.Value = this.style;
            }
 private void load(Bindable <Drawable> inspected)
 {
     inspectedDrawable = inspected.GetBoundCopy();
 }
Пример #17
0
        private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, Bindable <IEnumerable <Mod> > selectedMods)
        {
            if (selectedMods != null)
            {
                SelectedMods.BindTo(selectedMods);
            }

            if (Footer != null)
            {
                Footer.AddButton(@"mods", colours.Yellow, ModSelect, Key.F1);
                Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
                Footer.AddButton(@"options", colours.Blue, BeatmapOptions, Key.F3);

                BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.fa_trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue);
                BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
                BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, null, Key.Number2);
            }

            if (this.beatmaps == null)
            {
                this.beatmaps = beatmaps;
            }

            this.beatmaps.ItemAdded       += onBeatmapSetAdded;
            this.beatmaps.ItemRemoved     += onBeatmapSetRemoved;
            this.beatmaps.BeatmapHidden   += onBeatmapHidden;
            this.beatmaps.BeatmapRestored += onBeatmapRestored;

            dialogOverlay = dialog;

            sampleChangeDifficulty = audio.Sample.Get(@"SongSelect/select-difficulty");
            sampleChangeBeatmap    = audio.Sample.Get(@"SongSelect/select-expand");
            SampleConfirm          = audio.Sample.Get(@"SongSelect/confirm-selection");

            Carousel.LoadBeatmapSetsFromManager(this.beatmaps);

            if (dialogOverlay != null)
            {
                Schedule(() =>
                {
                    // if we have no beatmaps but osu-stable is found, let's prompt the user to import.
                    if (!beatmaps.GetAllUsableBeatmapSets().Any() && beatmaps.StableInstallationAvailable)
                    {
                        dialogOverlay.Push(new ImportFromStablePopup(() =>
                        {
                            beatmaps.ImportFromStableAsync();
                            skins.ImportFromStableAsync();
                        }));
                    }
                });
            }
        }
Пример #18
0
        private void load(OsuConfigManager config, OsuColour colours, ChannelManager channelManager)
        {
            const float padding = 5;

            Children = new Drawable[]
            {
                channelSelectionContainer = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                    Height           = 1f - DEFAULT_HEIGHT,
                    Masking          = true,
                    Children         = new[]
                    {
                        ChannelSelectionOverlay = new ChannelSelectionOverlay
                        {
                            RelativeSizeAxes = Axes.Both,
                        },
                    },
                },
                chatContainer = new Container
                {
                    Name             = @"chat container",
                    Anchor           = Anchor.BottomLeft,
                    Origin           = Anchor.BottomLeft,
                    RelativeSizeAxes = Axes.Both,
                    Height           = DEFAULT_HEIGHT,
                    Children         = new[]
                    {
                        new Container
                        {
                            Name             = @"chat area",
                            RelativeSizeAxes = Axes.Both,
                            Padding          = new MarginPadding {
                                Top = TAB_AREA_HEIGHT
                            },
                            Children = new Drawable[]
                            {
                                chatBackground = new Box
                                {
                                    RelativeSizeAxes = Axes.Both,
                                },
                                currentChannelContainer = new Container <DrawableChannel>
                                {
                                    RelativeSizeAxes = Axes.Both,
                                    Padding          = new MarginPadding
                                    {
                                        Bottom = textbox_height
                                    },
                                },
                                new Container
                                {
                                    Anchor           = Anchor.BottomLeft,
                                    Origin           = Anchor.BottomLeft,
                                    RelativeSizeAxes = Axes.X,
                                    Height           = textbox_height,
                                    Padding          = new MarginPadding
                                    {
                                        Top    = padding * 2,
                                        Bottom = padding * 2,
                                        Left   = ChatLine.LEFT_PADDING + padding * 2,
                                        Right  = padding * 2,
                                    },
                                    Children = new Drawable[]
                                    {
                                        textbox = new FocusedTextBox
                                        {
                                            RelativeSizeAxes     = Axes.Both,
                                            Height               = 1,
                                            PlaceholderText      = "type your message",
                                            OnCommit             = postMessage,
                                            ReleaseFocusOnCommit = false,
                                            HoldFocus            = true,
                                        }
                                    }
                                },
                                loading = new LoadingAnimation(),
                            }
                        },
                        tabsArea = new TabsArea
                        {
                            Children = new Drawable[]
                            {
                                tabBackground = new Box
                                {
                                    RelativeSizeAxes = Axes.Both,
                                    Colour           = Color4.Black,
                                },
                                ChannelTabControl = CreateChannelTabControl().With(d =>
                                {
                                    d.Anchor           = Anchor.BottomLeft;
                                    d.Origin           = Anchor.BottomLeft;
                                    d.RelativeSizeAxes = Axes.Both;
                                    d.OnRequestLeave   = channelManager.LeaveChannel;
                                }),
                            }
                        },
                    },
                },
            };

            ChannelTabControl.Current.ValueChanged += current => channelManager.CurrentChannel.Value = current.NewValue;
            ChannelTabControl.ChannelSelectorActive.ValueChanged += active => ChannelSelectionOverlay.State.Value = active.NewValue ? Visibility.Visible : Visibility.Hidden;
            ChannelSelectionOverlay.State.ValueChanged           += state =>
            {
                // Propagate the visibility state to ChannelSelectorActive
                ChannelTabControl.ChannelSelectorActive.Value = state.NewValue == Visibility.Visible;

                if (state.NewValue == Visibility.Visible)
                {
                    textbox.HoldFocus = false;
                    if (1f - ChatHeight.Value < channel_selection_min_height)
                    {
                        this.TransformBindableTo(ChatHeight, 1f - channel_selection_min_height, 800, Easing.OutQuint);
                    }
                }
                else
                {
                    textbox.HoldFocus = true;
                }
            };

            ChannelSelectionOverlay.OnRequestJoin  = channel => channelManager.JoinChannel(channel);
            ChannelSelectionOverlay.OnRequestLeave = channelManager.LeaveChannel;

            ChatHeight = config.GetBindable <float>(OsuSetting.ChatDisplayHeight);
            ChatHeight.BindValueChanged(height =>
            {
                chatContainer.Height             = height.NewValue;
                channelSelectionContainer.Height = 1f - height.NewValue;
                tabBackground.FadeTo(height.NewValue == 1f ? 1f : 0.8f, 200);
            }, true);

            chatBackground.Colour = colours.ChatBlue;

            this.channelManager = channelManager;

            loading.Show();

            // This is a relatively expensive (and blocking) operation.
            // Scheduling it ensures that it won't be performed unless the user decides to open chat.
            // TODO: Refactor OsuFocusedOverlayContainer / OverlayContainer to support delayed content loading.
            Schedule(() =>
            {
                // TODO: consider scheduling bindable callbacks to not perform when overlay is not present.
                channelManager.JoinedChannels.ItemsAdded   += onChannelAddedToJoinedChannels;
                channelManager.JoinedChannels.ItemsRemoved += onChannelRemovedFromJoinedChannels;
                foreach (Channel channel in channelManager.JoinedChannels)
                {
                    ChannelTabControl.AddChannel(channel);
                }

                channelManager.AvailableChannels.ItemsAdded   += availableChannelsChanged;
                channelManager.AvailableChannels.ItemsRemoved += availableChannelsChanged;
                ChannelSelectionOverlay.UpdateAvailableChannels(channelManager.AvailableChannels);

                currentChannel = channelManager.CurrentChannel.GetBoundCopy();
                currentChannel.BindValueChanged(currentChannelChanged, true);
            });
        }
Пример #19
0
 private void load(OsuColour colours, Bindable <RulesetInfo> ruleset)
 {
     DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark;
     rulesetSelector.Current.BindTo(ruleset);
 }
Пример #20
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="dialog"></param>
 /// <param name="name"></param>
 /// <param name="binded"></param>
 public SettingsScrollDirection(SettingsDialog dialog, string name, Bindable <ScrollDirection> binded)
     : base(dialog, name, ScrollDirectionToStringList(), (val, index) => OnChange(val, binded), (int)binded.Value)
 {
     BoundScrollDirection = binded;
     BoundScrollDirection.ValueChanged += OnBindableValueChanged;
 }
Пример #21
0
 private void load([NotNull] GameConfigManager config)
 {
     cursorRotate = config.GetBindable <bool>(CirclesSetting.CursorRotation);
 }
Пример #22
0
 /// <summary>
 ///     Is called when the UI is changed.
 /// </summary>
 /// <param name="val"></param>
 /// <param name="index"></param>
 /// <param name="binded"></param>
 private static void OnChange(string val, Bindable <ScrollDirection> binded) => binded.Value = (ScrollDirection)Enum.Parse(typeof(ScrollDirection), val);
Пример #23
0
        /// <inheritdoc />
        /// <summary>
        /// </summary>
        internal Scoreboard(ScoreboardType type, IEnumerable <ScoreboardUser> users, MultiplayerTeam team = MultiplayerTeam.Red)
        {
            Type = type;
            Team = team;

            if (OnlineManager.CurrentGame != null)
            {
                OnlineManager.Client.OnGameJudgements += OnGameJudgements;
                OnlineManager.Client.OnPlayerBattleRoyaleEliminated += OnPlayerBattleRoyaleEliminated;

                if (OnlineManager.CurrentGame.Ruleset == MultiplayerGameRuleset.Battle_Royale)
                {
                    BattleRoyalePlayersLeft = new Bindable <int>(0)
                    {
                        Value = MapManager.Selected.Value.Scores.Value.Count + 1
                    };
                }
            }

            if (Type == ScoreboardType.Teams)
            {
                TeamBanner = new ScoreboardTeamBanner(this)
                {
                    Parent = this,
                    Y      = 235,
                };

                if (Team == MultiplayerTeam.Blue)
                {
                    TeamBanner.X = WindowManager.Width - TeamBanner.Width;
                }
            }

            if (OnlineManager.CurrentGame?.Ruleset == MultiplayerGameRuleset.Battle_Royale)
            {
                BattleRoyaleBanner = new ScoreboardBattleRoyaleBanner(this)
                {
                    Parent = this,
                    Y      = 235
                };
            }
            else if (OnlineManager.CurrentGame?.Ruleset == MultiplayerGameRuleset.Free_For_All &&
                     MapManager.Selected.Value.Scores.Value.Count == 1)
            {
                OneVsOneWinsBanner = new ScoreboardOneVsOneWins(this)
                {
                    Parent = this,
                    Y      = 235
                };
            }

            Users = users.OrderBy(x => x.Processor.Health <= 0).ThenByDescending(x => x.RatingProcessor.CalculateRating(x.Processor.Accuracy)).ToList();
            SetTargetYPositions();

            Users.ForEach(x =>
            {
                x.Scoreboard = this;
                x.Y          = x.TargetYPosition;

                if (Team == MultiplayerTeam.Blue)
                {
                    x.X = WindowManager.Width;
                }
            });
        }
Пример #24
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,
                        Children         = new Drawable[]
                        {
                            DrawableRuleset,
                            new ComboEffects(ScoreProcessor)
                        }
                    }
                },
                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);
                        performImmediateExit();
                    },
                },
                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);
            }
        }
Пример #25
0
        private void load(AudioManager audio, OsuConfigManager config, OsuGameBase 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)
            {
                gameActive.BindTo(game.IsActive);
            }

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

            DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);

            ScoreProcessor = ruleset.CreateScoreProcessor();
            ScoreProcessor.ApplyBeatmap(playableBeatmap);
            ScoreProcessor.Mods.BindTo(Mods);

            dependencies.CacheAs(ScoreProcessor);

            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();
            }

            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);
                gameplayBeatmap.ApplyResult(r);
            };

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

            DimmableStoryboard.HasStoryboardEnded.ValueChanged += storyboardEnded =>
            {
                if (storyboardEnded.NewValue && completionProgressDelegate == null)
                {
                    updateCompletionState();
                }
            };

            // Bind the judgement processors to ourselves
            ScoreProcessor.HasCompleted.BindValueChanged(_ => 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);
        }
Пример #26
0
Файл: Player.cs Проект: gocs/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();

            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 = () => AllowPause && 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);

            hudOverlay.ReplaySettingsOverlay.PlaybackSettings.AdjustableClock = adjustableSourceClock;

            // 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 setupConfig()
        {
            Dependencies.Cache(debugConfig  = new FrameworkDebugConfigManager());
            Dependencies.Cache(config       = new FrameworkConfigManager(Storage));
            Dependencies.Cache(Localisation = new LocalisationEngine(config));

            activeGCMode = debugConfig.GetBindable <GCLatencyMode>(DebugSetting.ActiveGCMode);
            activeGCMode.ValueChanged += newMode =>
            {
                GCSettings.LatencyMode = IsActive ? newMode : GCLatencyMode.Interactive;
            };

            frameSyncMode = config.GetBindable <FrameSync>(FrameworkSetting.FrameSync);
            frameSyncMode.ValueChanged += newMode =>
            {
                float refreshRate = DisplayDevice.Default.RefreshRate;
                // For invalid refresh rates let's assume 60 Hz as it is most common.
                if (refreshRate <= 0)
                {
                    refreshRate = 60;
                }

                float drawLimiter   = refreshRate;
                float updateLimiter = drawLimiter * 2;

                setVSyncMode();

                switch (newMode)
                {
                case FrameSync.VSync:
                    drawLimiter    = int.MaxValue;
                    updateLimiter *= 2;
                    break;

                case FrameSync.Limit2x:
                    drawLimiter   *= 2;
                    updateLimiter *= 2;
                    break;

                case FrameSync.Limit4x:
                    drawLimiter   *= 4;
                    updateLimiter *= 4;
                    break;

                case FrameSync.Limit8x:
                    drawLimiter   *= 8;
                    updateLimiter *= 8;
                    break;

                case FrameSync.Unlimited:
                    drawLimiter = updateLimiter = int.MaxValue;
                    break;
                }

                if (DrawThread != null)
                {
                    DrawThread.ActiveHz = drawLimiter;
                }
                if (UpdateThread != null)
                {
                    UpdateThread.ActiveHz = updateLimiter;
                }
            };

            ignoredInputHandlers = config.GetBindable <string>(FrameworkSetting.IgnoredInputHandlers);
            ignoredInputHandlers.ValueChanged += ignoredString =>
            {
                var configIgnores = ignoredString.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));

                // for now, we always want at least one handler disabled (don't want raw and non-raw mouse at once).
                bool restoreDefaults = !configIgnores.Any();

                if (restoreDefaults)
                {
                    resetInputHandlers();
                    ignoredInputHandlers.Value = string.Join(" ", AvailableInputHandlers.Where(h => !h.Enabled).Select(h => h.ToString()));
                }
                else
                {
                    foreach (var handler in AvailableInputHandlers)
                    {
                        var handlerType = handler.ToString();
                        handler.Enabled.Value = configIgnores.All(ch => ch != handlerType);
                    }
                }
            };

            cursorSensitivity = config.GetBindable <double>(FrameworkSetting.CursorSensitivity);

            performanceLogging = config.GetBindable <bool>(FrameworkSetting.PerformanceLogging);
            performanceLogging.ValueChanged += enabled => threads.ForEach(t => t.Monitor.EnablePerformanceProfiling = enabled);
            performanceLogging.TriggerChange();
        }
Пример #28
0
 private void load(OsuConfigManager config)
 {
     mouseDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableButtons)
         ?? new Bindable<bool>(false);
 }
Пример #29
0
 protected PaginatedProfileSubsection(Bindable <APIUser> user, LocalisableString?headerText = null, LocalisableString?missingText = null)
     : base(user, headerText, CounterVisibilityState.AlwaysVisible)
 {
     this.missingText = missingText;
 }
Пример #30
0
 /// <summary>
 /// Create a new aggregate bindable.
 /// </summary>
 /// <param name="aggregateFunction">The function to be used for aggregation, taking two input <typeparamref name="T"/> values and returning one output.</param>
 /// <param name="resultBindable">An optional newly constructed bindable to use for <see cref="Result"/>. The initial value of this bindable is used as the initial value for the aggregate.</param>
 public AggregateBindable(Func <T, T, T> aggregateFunction, Bindable <T> resultBindable = null)
 {
     this.aggregateFunction = aggregateFunction;
     result       = resultBindable ?? new Bindable <T>();
     initialValue = result.Value;
 }
Пример #31
0
		/// <summary>
		/// Constructs a simple character controller.
		/// </summary>
		/// <param name="position">Location to initially place the character.</param>
		/// <param name="height">The height of the character.</param>
		/// <param name="radius">The diameter of the character.</param>
		/// <param name="supportHeight">The distance above the ground that the bottom of the character's body floats.</param>
		/// <param name="mass">Total mass of the character.</param>
		public Character(Main main, Bindable bindable, Vector3 position, float height = Character.DefaultHeight, float crouchedHeight = Character.DefaultCrouchedHeight, float radius = Character.DefaultRadius, float supportHeight = Character.DefaultSupportHeight, float crouchedSupportHeight = Character.DefaultCrouchedSupportHeight, float mass = Character.DefaultMass)
		{
			this.main = main;
			this.Radius.Value = radius;
			this.Mass.Value = mass;
			this.Body = new Capsule(position, height, radius, mass);
			this.Body.Tag = this;
			this.Body.CollisionInformation.Tag = this;
			this.Body.IgnoreShapeChanges = true;
			this.Body.LinearDamping = 0.0f;
			this.Body.CollisionInformation.CollisionRules.Group = Character.CharacterGroup;
			this.NormalHeight = height;
			this.CrouchedHeight = crouchedHeight;
			this.Body.CollisionInformation.Events.ContactCreated += new BEPUphysics.BroadPhaseEntries.Events.ContactCreatedEventHandler<EntityCollidable>(Events_ContactCreated);
			this.collisionPairCollector = new Box(position + new Vector3(0, (height * -0.5f) - supportHeight, 0), radius * 2, supportHeight * 2, radius, 1);
			this.collisionPairCollector.CollisionInformation.CollisionRules.Personal = CollisionRule.NoNarrowPhaseUpdate; //Prevents collision detection/contact generation from being run.
			this.collisionPairCollector.IsAffectedByGravity = false;
			this.collisionPairCollector.CollisionInformation.CollisionRules.Group = Character.CharacterGroup;
			CollisionRules.AddRule(this.collisionPairCollector, this.Body, CollisionRule.NoBroadPhase); //Prevents the creation of any collision pairs between the body and the collector.
			this.SupportHeight.Value = supportHeight;
			this.NormalSupportHeight = supportHeight;
			this.CrouchedSupportHeight = crouchedSupportHeight;

			this.Body.LocalInertiaTensorInverse = new BEPUutilities.Matrix3x3();
			this.collisionPairCollector.LocalInertiaTensorInverse = new BEPUutilities.Matrix3x3();

			bindable.Add(new ChangeBinding<bool>(this.Crouched, delegate(bool old, bool value)
			{
				if (value && !old)
				{
					this.Body.Position += new Vector3(0, (this.CrouchedSupportHeight - this.NormalSupportHeight) + 0.5f * (this.CrouchedHeight - this.NormalHeight), 0);
					this.Height.Value = this.CrouchedHeight;
					this.Body.Length = this.Height.Value - this.Radius * 2;
					this.SupportHeight.Value = this.CrouchedSupportHeight;
				}
				else if (!value && old)
				{
					this.Height.Value = this.NormalHeight;
					this.Body.Length = this.Height.Value - this.Radius * 2;
					this.Body.Position += new Vector3(0, (this.NormalSupportHeight - this.CrouchedSupportHeight) + 0.5f * (this.NormalHeight - this.CrouchedHeight), 0);
					this.SupportHeight.Value = this.NormalSupportHeight;
				}
				this.collisionPairCollector.Height = this.SupportHeight * 2;
				this.Transform.Value = this.Body.WorldTransform;
			}));

			bindable.Add(new SetBinding<Matrix>(this.Transform, delegate(Matrix m)
			{
				this.Body.WorldTransform = m;
			}));

			bindable.Add(new SetBinding<Vector3>(this.LinearVelocity, delegate(Vector3 v)
			{
				this.Body.LinearVelocity = v;
			}));

			//Make the body slippery.
			//Note that this will not make all collisions have zero friction;
			//the friction coefficient between a pair of objects is based
			//on a blending of the two objects' materials.
			this.Body.Material.KineticFriction = 0.0f;
			this.Body.Material.StaticFriction = 0.0f;
			this.Body.Material.Bounciness = 0.0f;

			const int rayChecks = 4;
			float rayCheckRadius = radius - 0.1f;
			this.rayOffsets = new[] { Vector3.Zero }.Concat(Enumerable.Range(0, rayChecks).Select(
			delegate(int x)
			{
				float angle = x * ((2.0f * (float)Math.PI) / (float)rayChecks);
				return new Vector3((float)Math.Cos(angle) * rayCheckRadius, 0, (float)Math.Sin(angle) * rayCheckRadius);
			})).ToArray();
			this.IsUpdating = false;
		}
Пример #32
0
 public PaginatedMostPlayedBeatmapContainer(Bindable <APIUser> user)
     : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle)
 {
 }
Пример #33
0
        private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuGameBase game)
        {
            dimLevel = game.Config.GetBindable<int>(OsuConfig.DimLevel);
            try
            {
                if (Beatmap == null)
                    Beatmap = beatmaps.GetWorkingBeatmap(BeatmapInfo);
            }
            catch
            {
                //couldn't load, hard abort!
                Exit();
                return;
            }

            AudioTrack track = Beatmap.Track;

            if (track != null)
            {
                audio.Track.SetExclusive(track);
                sourceClock = track;
            }

            sourceClock = (IAdjustableClock)track ?? new StopwatchClock();

            Schedule(() =>
            {
                sourceClock.Reset();
            });

            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;
            }

            PlayMode usablePlayMode = beatmap.BeatmapInfo?.Mode > PlayMode.Osu ? beatmap.BeatmapInfo.Mode : PreferredPlayMode;

            ruleset = Ruleset.GetRuleset(usablePlayMode);

            var scoreOverlay = ruleset.CreateScoreOverlay();
            scoreOverlay.BindProcessor(scoreProcessor = ruleset.CreateScoreProcessor());

            hitRenderer = ruleset.CreateHitRendererWith(beatmap.HitObjects);

            hitRenderer.OnJudgement += scoreProcessor.AddJudgement;
            hitRenderer.OnAllJudged += hitRenderer_OnAllJudged;

            if (Autoplay)
                hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Hit));

            Children = new Drawable[]
            {
                new PlayerInputManager(game.Host)
                {
                    Clock = new InterpolatingFramedClock(sourceClock),
                    PassThrough = false,
                    Children = new Drawable[]
                    {
                        hitRenderer,
                    }
                },
                scoreOverlay,
            };
        }
Пример #34
0
 public RoomScreen(OnlineRoom room)
 {
     this.room = new Bindable <OnlineRoom>(room);
 }
Пример #35
0
 private void load(OsuGameBase game)
 {
     if (beatmap == null)
         beatmap = game?.Beatmap;
 }
Пример #36
0
        private void load(OsuGameBase osuGame, BeatmapDatabase beatmaps, AudioManager audio,
            TextureStore textures, OsuColour colours)
        {
            Children = new Drawable[]
            {
                title = new SpriteText
                {
                    Origin = Anchor.BottomCentre,
                    Anchor = Anchor.TopCentre,
                    Position = new Vector2(0, 40),
                    TextSize = 25,
                    Colour = Color4.White,
                    Text = @"Nothing to play",
                    Font = @"Exo2.0-MediumItalic"
                },
                artist = new SpriteText
                {
                    Origin = Anchor.TopCentre,
                    Anchor = Anchor.TopCentre,
                    Position = new Vector2(0, 45),
                    TextSize = 15,
                    Colour = Color4.White,
                    Text = @"Nothing to play",
                    Font = @"Exo2.0-BoldItalic"
                },
                new ClickableContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Origin = Anchor.Centre,
                    Anchor = Anchor.BottomCentre,
                    Position = new Vector2(0, -30),
                    Action = () =>
                    {
                        if (current?.Track == null) return;
                        if (current.Track.IsRunning)
                            current.Track.Stop();
                        else
                            current.Track.Start();
                    },
                    Children = new Drawable[]
                    {
                        playButton = new TextAwesome
                        {
                            TextSize = 30,
                            Icon = FontAwesome.fa_play_circle_o,
                            Origin = Anchor.Centre,
                            Anchor = Anchor.Centre
                        }
                    }
                },
                new ClickableContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Origin = Anchor.Centre,
                    Anchor = Anchor.BottomCentre,
                    Position = new Vector2(-30, -30),
                    Action = prev,
                    Children = new Drawable[]
                    {
                        new TextAwesome
                        {
                            TextSize = 15,
                            Icon = FontAwesome.fa_step_backward,
                            Origin = Anchor.Centre,
                            Anchor = Anchor.Centre
                        }
                    }
                },
                new ClickableContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Origin = Anchor.Centre,
                    Anchor = Anchor.BottomCentre,
                    Position = new Vector2(30, -30),
                    Action = next,
                    Children = new Drawable[]
                    {
                        new TextAwesome
                        {
                            TextSize = 15,
                            Icon = FontAwesome.fa_step_forward,
                            Origin = Anchor.Centre,
                            Anchor = Anchor.Centre
                        }
                    }
                },
                new ClickableContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Origin = Anchor.Centre,
                    Anchor = Anchor.BottomRight,
                    Position = new Vector2(20, -30),
                    Children = new Drawable[]
                    {
                        listButton = new TextAwesome
                        {
                            TextSize = 15,
                            Icon = FontAwesome.fa_bars,
                            Origin = Anchor.Centre,
                            Anchor = Anchor.Centre
                        }
                    }
                },
                progress = new DragBar
                {
                    Origin = Anchor.BottomCentre,
                    Anchor = Anchor.BottomCentre,
                    Height = 10,
                    Colour = colours.Yellow,
                    SeekRequested = seek
                }
            };
        
            this.beatmaps = beatmaps;
            trackManager = osuGame.Audio.Track;
            config = osuGame.Config;
            preferUnicode = osuGame.Config.GetBindable<bool>(OsuConfig.ShowUnicode);
            preferUnicode.ValueChanged += preferUnicode_changed;

            beatmapSource = osuGame.Beatmap ?? new Bindable<WorkingBeatmap>();
            playList = beatmaps.GetAllWithChildren<BeatmapSetInfo>();

            backgroundSprite = new MusicControllerBackground();
            AddInternal(backgroundSprite);
        }
Пример #37
0
        private void load(Storage storage, GameHost host, FrameworkConfigManager frameworkConfig, FontStore fonts, Game game)
        {
            interactive = host.Window != null;
            config      = new TestBrowserConfig(storage);

            exit = host.Exit;

            var resources = game.Resources;

            //Roboto
            fonts.AddStore(new GlyphStore(resources, @"Fonts/Roboto/Roboto-Regular"));
            fonts.AddStore(new GlyphStore(resources, @"Fonts/Roboto/Roboto-Bold"));

            //RobotoCondensed
            fonts.AddStore(new GlyphStore(resources, @"Fonts/RobotoCondensed/RobotoCondensed-Regular"));
            fonts.AddStore(new GlyphStore(resources, @"Fonts/RobotoCondensed/RobotoCondensed-Bold"));

            showLogOverlay = frameworkConfig.GetBindable <bool>(FrameworkSetting.ShowLogOverlay);

            var rateAdjustClock = new StopwatchClock(true);
            var framedClock     = new FramedClock(rateAdjustClock);

            Children = new Drawable[]
            {
                leftContainer = new Container
                {
                    RelativeSizeAxes = Axes.Y,
                    Size             = new Vector2(test_list_width, 1),
                    Children         = new Drawable[]
                    {
                        new Box
                        {
                            Colour           = FrameworkColour.GreenDark,
                            RelativeSizeAxes = Axes.Both
                        },
                        new FillFlowContainer
                        {
                            Direction        = FillDirection.Vertical,
                            RelativeSizeAxes = Axes.Both,
                            Children         = new Drawable[]
                            {
                                searchTextBox = new TextBox
                                {
                                    OnCommit = delegate
                                    {
                                        var firstTest = leftFlowContainer.Where(b => b.IsPresent).SelectMany(b => b.FilterableChildren).OfType <TestCaseSubButton>().FirstOrDefault(b => b.MatchingFilter)?.TestType;
                                        if (firstTest != null)
                                        {
                                            LoadTest(firstTest);
                                        }
                                    },
                                    Height           = 20,
                                    RelativeSizeAxes = Axes.X,
                                    PlaceholderText  = "type to search"
                                },
                                new ScrollContainer
                                {
                                    Padding = new MarginPadding {
                                        Top = 3, Bottom = 20
                                    },
                                    RelativeSizeAxes = Axes.Both,
                                    Child            = leftFlowContainer = new SearchContainer <TestCaseButtonGroup>
                                    {
                                        Padding          = new MarginPadding(3),
                                        Direction        = FillDirection.Vertical,
                                        AutoSizeAxes     = Axes.Y,
                                        RelativeSizeAxes = Axes.X,
                                    }
                                }
                            }
                        }
                    }
                },
                mainContainer = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                    Padding          = new MarginPadding {
                        Left = test_list_width
                    },
                    Children = new Drawable[]
                    {
                        toolbar = new TestBrowserToolbar
                        {
                            RelativeSizeAxes = Axes.X,
                            Height           = 50,
                            Depth            = -1,
                        },
                        testContentContainer = new Container
                        {
                            Clock            = framedClock,
                            RelativeSizeAxes = Axes.Both,
                            Padding          = new MarginPadding {
                                Top = 50
                            },
                            Child = compilingNotice = new Container
                            {
                                Alpha        = 0,
                                Anchor       = Anchor.Centre,
                                Origin       = Anchor.Centre,
                                Masking      = true,
                                Depth        = float.MinValue,
                                CornerRadius = 5,
                                AutoSizeAxes = Axes.Both,
                                Children     = new Drawable[]
                                {
                                    new Box
                                    {
                                        RelativeSizeAxes = Axes.Both,
                                        Colour           = Color4.Black,
                                    },
                                    new SpriteText
                                    {
                                        Font = new FontUsage(size: 30),
                                        Text = @"Compiling new version..."
                                    }
                                },
                            }
                        }
                    }
                }
            };

            searchTextBox.Current.ValueChanged += e => leftFlowContainer.SearchTerm = e.NewValue;

            if (RuntimeInfo.SupportsJIT)
            {
                backgroundCompiler = new DynamicClassCompiler <TestCase>
                {
                    CompilationStarted  = compileStarted,
                    CompilationFinished = compileFinished,
                    CompilationFailed   = compileFailed
                };
                try
                {
                    backgroundCompiler.Start();
                }
                catch
                {
                    //it's okay for this to fail for now.
                }
            }

            foreach (Assembly asm in assemblies)
            {
                toolbar.AddAssembly(asm.GetName().Name, asm);
            }

            Assembly.BindValueChanged(updateList);
            RunAllSteps.BindValueChanged(v => runTests(null));
            PlaybackRate.BindValueChanged(e => rateAdjustClock.Rate = e.NewValue, true);
        }
Пример #38
0
 private void load(OsuConfigManager config)
 {
     InternalChild   = comboBreakSample = new SkinnableSound(new SampleInfo("Gameplay/combobreak"));
     alwaysPlayFirst = config.GetBindable <bool>(OsuSetting.AlwaysPlayFirstComboBreak);
 }
Пример #39
0
        private void load(BeatmapDatabase beatmaps, AudioManager audio, BaseGame game,
            OsuGame osuGame, OsuColour colours)
        {
            const float carouselWidth = 640;
            const float bottomToolHeight = 50;
            Children = new Drawable[]
            {
                new ParallaxContainer
                {
                    ParallaxAmount = 0.005f,
                    RelativeSizeAxes = Axes.Both,
                    Children = new []
                    {
                        new WedgeBackground
                        {
                            RelativeSizeAxes = Axes.Both,
                            Padding = new MarginPadding { Right = carouselWidth * 0.76f },
                        },
                    }
                },
                carousel = new CarouselContainer
                {
                    RelativeSizeAxes = Axes.Y,
                    Size = new Vector2(carouselWidth, 1),
                    Anchor = Anchor.CentreRight,
                    Origin = Anchor.CentreRight,
                },
                beatmapInfoWedge = new BeatmapInfoWedge
                {
                    Alpha = 0,
                    Position = wedged_container_start_position,
                    Size = wedged_container_size,
                    RelativeSizeAxes = Axes.X,
                    Margin = new MarginPadding { Top = 20, Right = 20, },
                },
                new Container
                {
                    RelativeSizeAxes = Axes.X,
                    Height = bottomToolHeight,
                    Anchor = Anchor.BottomCentre,
                    Origin = Anchor.BottomCentre,
                    Children = new Drawable[]
                    {
                        new Box
                        {
                            RelativeSizeAxes = Axes.Both,
                            Size = Vector2.One,
                            Colour = Color4.Black.Opacity(0.5f),
                        },
                        new BackButton
                        {
                            Anchor = Anchor.BottomLeft,
                            Origin = Anchor.BottomLeft,
                            //RelativeSizeAxes = Axes.Y,
                            Action = () => Exit()
                        },
                        new Button
                        {
                            Anchor = Anchor.CentreRight,
                            Origin = Anchor.CentreRight,
                            RelativeSizeAxes = Axes.Y,
                            Width = 100,
                            Text = "Play",
                            Colour = colours.Pink,
                            Action = start
                        },
                    }
                }
            };
        
            if (osuGame != null)
            {
                playMode = osuGame.PlayMode;
                playMode.ValueChanged += playMode_ValueChanged;
            }

            if (database == null)
                database = beatmaps;

            database.BeatmapSetAdded += onDatabaseOnBeatmapSetAdded;

            trackManager = audio.Track;

            sampleChangeDifficulty = audio.Sample.Get(@"SongSelect/select-difficulty");
            sampleChangeBeatmap = audio.Sample.Get(@"SongSelect/select-expand");

            initialAddSetsTask = new CancellationTokenSource();

            Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token);
        }
Пример #40
0
        private void load(FrameworkConfigManager frameworkConfig)
        {
            this.frameworkConfig = frameworkConfig;

            if (!Host.IsPrimaryInstance && !DebugUtils.IsDebugBuild)
            {
                Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error);
                Environment.Exit(0);
            }

            if (args?.Length > 0)
            {
                var paths = args.Where(a => !a.StartsWith(@"-")).ToArray();
                if (paths.Length > 0)
                {
                    Task.Run(() => Import(paths));
                }
            }

            dependencies.CacheAs(this);

            dependencies.Cache(RavenLogger);

            dependencies.Cache(osuLogo = new OsuLogo {
                Alpha = 0
            });

            // bind config int to database RulesetInfo
            configRuleset         = LocalConfig.GetBindable <int>(OsuSetting.Ruleset);
            Ruleset.Value         = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First();
            Ruleset.ValueChanged += r => configRuleset.Value = r.NewValue.ID ?? 0;

            // bind config int to database SkinInfo
            configSkin = LocalConfig.GetBindable <int>(OsuSetting.Skin);
            SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID;
            configSkin.ValueChanged += skinId =>
            {
                var skinInfo = SkinManager.Query(s => s.ID == skinId.NewValue);

                if (skinInfo == null)
                {
                    switch (skinId.NewValue)
                    {
                    case -1:
                        skinInfo = DefaultLegacySkin.Info;
                        break;

                    default:
                        skinInfo = SkinInfo.Default;
                        break;
                    }
                }

                SkinManager.CurrentSkinInfo.Value = skinInfo;
            };
            configSkin.TriggerChange();

            IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true);

            Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade);

            Beatmap.BindValueChanged(beatmapChanged, true);
        }
Пример #41
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
            };

            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();

            // 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();
            config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);

            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;
            hudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded);

            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);
            }
        }
Пример #42
0
            private void load(OsuConfigManager config, IBindable <WorkingBeatmap> beatmap)
            {
                InternalChild = expandTarget = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                    Origin           = Anchor.Centre,
                    Anchor           = Anchor.Centre,
                    Child            = scaleTarget = new SkinnableDrawable("cursor", _ => new CircularContainer
                    {
                        RelativeSizeAxes = Axes.Both,
                        Masking          = true,
                        BorderThickness  = Size.X / 6,
                        BorderColour     = Color4.White,
                        EdgeEffect       = new EdgeEffectParameters
                        {
                            Type   = EdgeEffectType.Shadow,
                            Colour = Color4.Pink.Opacity(0.5f),
                            Radius = 5,
                        },
                        Children = new Drawable[]
                        {
                            new Box
                            {
                                RelativeSizeAxes = Axes.Both,
                                Alpha            = 0,
                                AlwaysPresent    = true,
                            },
                            new CircularContainer
                            {
                                Origin           = Anchor.Centre,
                                Anchor           = Anchor.Centre,
                                RelativeSizeAxes = Axes.Both,
                                Masking          = true,
                                BorderThickness  = Size.X / 3,
                                BorderColour     = Color4.White.Opacity(0.5f),
                                Children         = new Drawable[]
                                {
                                    new Box
                                    {
                                        RelativeSizeAxes = Axes.Both,
                                        Alpha            = 0,
                                        AlwaysPresent    = true,
                                    },
                                },
                            },
                            new CircularContainer
                            {
                                Origin           = Anchor.Centre,
                                Anchor           = Anchor.Centre,
                                RelativeSizeAxes = Axes.Both,
                                Scale            = new Vector2(0.1f),
                                Masking          = true,
                                Children         = new Drawable[]
                                {
                                    new Box
                                    {
                                        RelativeSizeAxes = Axes.Both,
                                        Colour           = Color4.White,
                                    },
                                },
                            },
                        }
                    }, restrictSize: false)
                    {
                        Origin           = Anchor.Centre,
                        Anchor           = Anchor.Centre,
                        RelativeSizeAxes = Axes.Both,
                    }
                };

                this.beatmap.BindTo(beatmap);
                this.beatmap.ValueChanged += v => calculateScale();

                cursorScale = config.GetBindable <double>(OsuSetting.GameplayCursorSize);
                cursorScale.ValueChanged += v => calculateScale();

                autoCursorScale = config.GetBindable <bool>(OsuSetting.AutoCursorSize);
                autoCursorScale.ValueChanged += v => calculateScale();

                calculateScale();
            }