public OtherSettingsViewModel(GameSettingsUpdater settingsUpdater, Languages languages)
        {
            Func <GameSettings> s = () => settingsUpdater.CurrentSettings;

            var availableLanguages = languages.MetaInfo.Values.ToList();
            var cultureCodes       = availableLanguages.Select(l => l.CultureCode.ToString()).ToList();

            Language = new GuiComponentDescriptor.List(
                "language",
                availableLanguages
                .Select(languageInfo => languageInfo.EnglishName + " / " + languageInfo.Name)
                .ToArray(),
                updateIndex: settingsUpdater.Updater <int>((settings, newIndex) => {
                settings.Other.Language = cultureCodes[newIndex];
                return(settings);
            }),
                currentIndex: () => cultureCodes.IndexOf(s().Other.Language));

            AutomaticServerPort = new GuiComponentDescriptor.Boolean(
                "automatic_server_port",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Other.AutomaticNetworkPort = value;
                return(settings);
            }),
                isChecked: () => s().Other.AutomaticNetworkPort);
            ServerPort = new GuiComponentDescriptor.Range(
                "server_port",
                minValue: 1024f,
                maxValue: 65535f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Other.NetworkPort = (int)value;
                return(settings);
            }),
                currentValue: () => s().Other.NetworkPort,
                updateDisplayValue: (descriptor, str) => {
                descriptor.IsVisible = !s().Other.AutomaticNetworkPort;
                GuiComponentDescriptor.DisplayNumber(s().Other.NetworkPort, str, decimalPlaces: 0);
            });
        }
Esempio n. 2
0
        public OptionsMenuModel(GameSettingsProvider gameSettingsProvider, Languages languages, string appVersion,
                                Action <InputBindingViewModel> startRebind,
                                Action <InputDefaults> restoreInputToDefaults)
        {
            MenuStack = new Stack <Menu>();
            MenuStack.Push(Menu.Main);

            AppVersion              = "v" + appVersion;
            _inputBindings          = null;
            _menuState              = MenuId.StartSelection;
            _gameSettingsProvider   = gameSettingsProvider;
            _restoreInputToDefaults = restoreInputToDefaults;
            _startRebind            = startRebind;
            _gameSettingsUpdater    = new GameSettingsUpdater(gameSettingsProvider);
            AudioSettings           = new AudioSettingsViewModel(_gameSettingsUpdater);
            GraphicsSettings        = new GraphicsSettingsViewModel(_gameSettingsUpdater);
            GameplaySettings        = new GameplaySettingsViewModel(_gameSettingsUpdater);
            TimeAndWeatherSettings  = new TimeAndWeatherSettingsViewModel(_gameSettingsUpdater);
            InputSettings           = new InputSettingsViewModel(_gameSettingsUpdater);
            OtherSettings           = new OtherSettingsViewModel(_gameSettingsUpdater, languages);

            _gameSettingsProvider.SettingChanges.Subscribe(OnUpdate);
            _gameSettingsUpdater.OnUnappliedSettingsUpdated += unappliedSettings => OnUpdate();
        }
Esempio n. 3
0
        public GraphicsSettingsViewModel(GameSettingsUpdater settingsUpdater)
        {
            Func <GameSettings> s    = () => settingsUpdater.CurrentSettings;
            var availableResolutions = GetScreenResolutions(s().Graphics.ScreenResolution);

            ScreenResolution = new GuiComponentDescriptor.List(
                "screen_resolution",
                availableResolutions.Select(r => r.Width + "×" + r.Height).ToArray(),
                updateIndex: newIndex => {
                var unappliedSettings = settingsUpdater.UnappliedSettings;
                unappliedSettings.ScreenResolution = availableResolutions[newIndex];
                settingsUpdater.UnappliedSettings  = unappliedSettings;
            },
                currentIndex: () => {
                var unappliedSettings = settingsUpdater.UnappliedSettings;
                Resolution resolution;
                if (unappliedSettings.ScreenResolution.HasValue)
                {
                    resolution = unappliedSettings.ScreenResolution.Value;
                }
                else
                {
                    resolution = s().Graphics.ScreenResolution;
                }
                return(availableResolutions.IndexOf(resolution));
            });
            IsWindowed = new GuiComponentDescriptor.Boolean(
                "windowed",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Graphics.IsWindowed = value;
                return(settings);
            }),
                isChecked: () => s().Graphics.IsWindowed);
            FieldOfView = new GuiComponentDescriptor.Range(
                "field_of_view",
                minValue: 60f,
                maxValue: 120f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.FieldOfView = Mathf.RoundToInt(value);
                return(settings);
            }),
                currentValue: () => s().Graphics.FieldOfView,
                updateDisplayValue: (descriptor, str) => {
                descriptor.IsEnabled = true;
                GuiComponentDescriptor.DisplayNumber(s().Graphics.FieldOfView, str, decimalPlaces: 0,
                                                     postFix: "°");
            });
            ScreenshotMagnification = new GuiComponentDescriptor.Range(
                "screenshot_magnification",
                minValue: 0.5f,
                maxValue: 4f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.ScreenshotMagnificationFactor = value;
                return(settings);
            }),
                currentValue: () => s().Graphics.ScreenshotMagnificationFactor,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.ScreenshotMagnificationFactor, str,
                                                     decimalPlaces: 1, postFix: " ×");
            },
                stepSize: 0.1f);
            ScreenShakeIntensity = new GuiComponentDescriptor.Range(
                "screen_shake_intensity",
                minValue: 0f,
                maxValue: 2f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.ScreenShakeIntensity = value;
                return(settings);
            }),
                currentValue: () => s().Graphics.ScreenShakeIntensity,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.ScreenShakeIntensity, str, decimalPlaces: 1);
            },
                stepSize: 0.1f);
            TargetFrameRate = new GuiComponentDescriptor.Range(
                "target_framerate",
                minValue: 30f,
                maxValue: 120f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.TargetFrameRate = Mathf.RoundToInt(value);
                return(settings);
            }),
                currentValue: () => s().Graphics.TargetFrameRate,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.TargetFrameRate, str, decimalPlaces: 0,
                                                     postFix: " fps");
            });
            TextureQuality = new GuiComponentDescriptor.List(
                "texture_quality",
                GuiComponentDescriptor.GetEnumStrings <TextureQuality>("texq"),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Graphics.TextureQuality = EnumUtils.GetValues <TextureQuality>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Graphics.TextureQuality));
            AnisotropicFilteringMode = new GuiComponentDescriptor.List(
                "anisotropic_filtering",
                GuiComponentDescriptor.GetEnumStrings <AnisotropicFilteringMode>("aniso"),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Graphics.AnisotropicFilteringMode = EnumUtils.GetValues <AnisotropicFilteringMode>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Graphics.AnisotropicFilteringMode));
            ShadowQuality = new GuiComponentDescriptor.List(
                "shadow_quality",
                GuiComponentDescriptor.GetEnumStrings <VoloShadowQuality>(),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Graphics.VoloShadowQuality = EnumUtils.GetValues <VoloShadowQuality>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Graphics.VoloShadowQuality));
            ShadowDistance = new GuiComponentDescriptor.Range(
                "shadow_distance",
                minValue: 0f,
                maxValue: 2000f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.ShadowDistance = value;
                return(settings);
            }),
                currentValue: () => s().Graphics.ShadowDistance,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.ShadowDistance, str, decimalPlaces: 0,
                                                     postFix: " m");
            },
                stepSize: 20f);
//            TreeQuality = new GuiComponentDescriptor.List(
//                "tree_quality",
//                GuiComponentDescriptor.GetEnumStrings<TreeQuality>(),
//                updateIndex: settingsUpdater.Updater<int>((settings, index) => {
//                    settings.Graphics.TreeQuality = EnumUtils.GetValues<TreeQuality>()[index];
//                    return settings;
//                }),
//                currentIndex: () => EnumUtils.IndexOf(s().Graphics.TreeQuality));
            DetailObjectDistance = new GuiComponentDescriptor.Range(
                "grass_view_distance",
                minValue: 0f,
                maxValue: 7f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.DetailObjectDistance = Mathf.RoundToInt(value);
                return(settings);
            }),
                currentValue: () => s().Graphics.DetailObjectDistance,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.DetailObjectDistance, str, decimalPlaces: 0);
            });
            DetailObjectDensity = new GuiComponentDescriptor.Range(
                "grass_density",
                minValue: 1f,
                maxValue: 5f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.DetailObjectDensity = Mathf.RoundToInt(value);
                return(settings);
            }),
                currentValue: () => s().Graphics.DetailObjectDensity,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.DetailObjectDensity, str, decimalPlaces: 0);
            });
            MaxParticles = new GuiComponentDescriptor.Range(
                "max_number_of_particles",
                minValue: 0f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.MaxParticles = value;
                return(settings);
            }),
                currentValue: () => s().Graphics.MaxParticles,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayPercentage(s().Graphics.MaxParticles, str);
            },
                stepSize: 0.01f);
            TerrainRenderingAccuracy = new GuiComponentDescriptor.Range(
                "terrain_rendering_accuracy",
                minValue: 0f,
                maxValue: 47f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.TerrainRenderingAccuracy = 50f - value;
                return(settings);
            }),
                currentValue: () => 50f - s().Graphics.TerrainRenderingAccuracy,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Graphics.TerrainRenderingAccuracy, str, decimalPlaces: 0,
                                                     postFix: ":1 px");
            });
            TerrainCastShadows = new GuiComponentDescriptor.Boolean(
                "cast_terrain_shadows",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Graphics.TerrainCastShadows = value;
                return(settings);
            }),
                isChecked: () => s().Graphics.TerrainCastShadows);
            BloomQuality = new GuiComponentDescriptor.List(
                "bloom",
                GuiComponentDescriptor.GetEnumStrings <BloomQuality>(),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Graphics.BloomQuality = EnumUtils.GetValues <BloomQuality>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Graphics.BloomQuality));
            MotionBlurQualitySteps = new GuiComponentDescriptor.Range(
                "motion_blur",
                minValue: 0f,
                maxValue: 20f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Graphics.MotionBlurQualitySteps = Mathf.RoundToInt(value);
                return(settings);
            }),
                currentValue: () => s().Graphics.MotionBlurQualitySteps,
                updateDisplayValue: (descriptor, displayStr) => {
                var value = s().Graphics.MotionBlurQualitySteps;
                if (value == 0)
                {
                    displayStr.Append("off");
                }
                else
                {
                    displayStr.Append(value);
                }
            });
            AntiAliasingMode = new GuiComponentDescriptor.List(
                "anti_aliasing_mode",
                GuiComponentDescriptor.GetEnumStrings <AntiAliasingMode>(),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Graphics.AntiAliasingMode = EnumUtils.GetValues <AntiAliasingMode>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Graphics.AntiAliasingMode));
            AntiAliasingQuality = new GuiComponentDescriptor.List(
                "anti_aliasing_quality",
                GuiComponentDescriptor.GetEnumStrings <AntiAliasingQuality>(),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Graphics.AntiAliasingQuality = EnumUtils.GetValues <AntiAliasingQuality>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Graphics.AntiAliasingQuality));
            VSync = new GuiComponentDescriptor.Boolean(
                "vsync",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Graphics.IsVSyncEnabled = value;
                return(settings);
            }),
                isChecked: () => s().Graphics.IsVSyncEnabled);
        }
Esempio n. 4
0
        public TimeAndWeatherSettingsViewModel(GameSettingsUpdater settingsUpdater)
        {
            Func <GameSettings> s = () => settingsUpdater.CurrentSettings;
            Func <CultureInfo>  currentCultureInfo = () => CultureInfoUtil.GetCulture(s().Other.Language);

            IsTimeSimulated = new GuiComponentDescriptor.Boolean(
                "simulate_time",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.Time.IsTimeSimulated = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.Time.IsTimeSimulated);
            CurrentTime = new GuiComponentDescriptor.Range(
                "current_time",
                minValue: 0f,
                maxValue: 23.999f,
                updateValue: settingsUpdater.Updater <float>((settings, hour) => {
                var currentDateTime = settings.Gameplay.Time.CurrentDateTime;
                settings.Gameplay.Time.CurrentDateTime = new DateTime(
                    currentDateTime.Year,
                    currentDateTime.Month,
                    currentDateTime.Day,
                    hour: 0,
                    minute: 0,
                    second: 0,
                    millisecond: 0,
                    kind: currentDateTime.Kind) + TimeSpan.FromHours(hour);
                return(settings);
            }),
                currentValue: () => {
                var currentDate = s().Gameplay.Time.CurrentDateTime;
                return(currentDate.Hour + (currentDate.Minute / 60f));
            },
                updateDisplayValue: (descritor, str) => {
                var currentDateTime = s().Gameplay.Time.CurrentDateTime;
                str.Append(currentDateTime.ToString("t", currentCultureInfo()));
            },
                stepSize: 0.16666667f);
            CurrentDate = new GuiComponentDescriptor.Range(
                "current_day",
                minValue: 1f,
                maxValue: 365f,
                updateValue: settingsUpdater.Updater <float>((settings, newDayOfYear) => {
                var currentDateTime = settings.Gameplay.Time.CurrentDateTime;
                settings.Gameplay.Time.CurrentDateTime = currentDateTime.SetDayOfYear((int)newDayOfYear);
                return(settings);
            }),
                currentValue: () => {
                var currentDate = s().Gameplay.Time.CurrentDateTime;
                return(currentDate.DayOfYear);
            },
                updateDisplayValue: (newDayOfYear, str) => {
                var currentDate = s().Gameplay.Time.CurrentDateTime;
                str.Append(currentDate.ToString("m", currentCultureInfo()));
            });
            DayLengthInMinutes = new GuiComponentDescriptor.Range(
                "day_length_in_minutes",
                minValue: 1f,
                maxValue: 200f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.Time.DayLengthInMinutes = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.Time.DayLengthInMinutes,
                updateDisplayValue: (descriptor, str) => {
                GuiComponentDescriptor.DisplayNumber(s().Gameplay.Time.DayLengthInMinutes, str, decimalPlaces: 0);
            });
            IsNightSkipped = new GuiComponentDescriptor.Boolean(
                "skip_night",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.Time.IsNightSkipped = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.Time.IsNightSkipped);
            IsWeatherSimulated = new GuiComponentDescriptor.Boolean(
                "simulate_weather",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.Weather.IsWeatherSimulated = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.Weather.IsWeatherSimulated);
            SnowAltitude = new GuiComponentDescriptor.Range(
                "snow_altitude",
                minValue: 2000f,
                maxValue: 3300,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.Weather.SnowAltitude = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.Weather.SnowAltitude,
                updateDisplayValue: (descriptor, str) => {
                descriptor.IsVisible = !s().Gameplay.Weather.IsWeatherSimulated;
                GuiComponentDescriptor.DisplayNumber(s().Gameplay.Weather.SnowAltitude, str, decimalPlaces: 0, postFix: "m");
            },
                stepSize: 20f);
            SnowfallIntensity = new GuiComponentDescriptor.Range(
                "snowfall_intensity",
                minValue: 0f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.Weather.SnowfallIntensity = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.Weather.SnowfallIntensity,
                updateDisplayValue: (descriptor, str) => {
                descriptor.IsVisible = !s().Gameplay.Weather.IsWeatherSimulated;
                GuiComponentDescriptor.DisplayPercentage(s().Gameplay.Weather.SnowfallIntensity, str);
            },
                stepSize: 0.02f);
            FogIntensity = new GuiComponentDescriptor.Range(
                "fog_intensity",
                minValue: 0f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.Weather.FogIntensity = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.Weather.FogIntensity,
                updateDisplayValue: (descriptor, str) => {
                descriptor.IsVisible = !s().Gameplay.Weather.IsWeatherSimulated;
                GuiComponentDescriptor.DisplayPercentage(s().Gameplay.Weather.FogIntensity, str);
            },
                stepSize: 0.02f);
            DaysPerSeason = new GuiComponentDescriptor.Range(
                "days_per_season",
                minValue: 1f,
                maxValue: 178f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.Weather.DaysPerSeason = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.Weather.DaysPerSeason,
                updateDisplayValue: (descriptor, str) => {
                descriptor.IsVisible = s().Gameplay.Weather.IsWeatherSimulated;
                GuiComponentDescriptor.DisplayNumber(s().Gameplay.Weather.DaysPerSeason, str, decimalPlaces: 0);
            });
        }
        public GameplaySettingsViewModel(GameSettingsUpdater settingsUpdater)
        {
            Func <GameSettings> s = () => settingsUpdater.CurrentSettings;

            ShowHud = new GuiComponentDescriptor.Boolean(
                "show_hud",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.ShowHud = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.ShowHud);
            UnitSystem = new GuiComponentDescriptor.List(
                "unit_system",
                GuiComponentDescriptor.GetEnumStrings <UnitSystem>(),
                updateIndex: settingsUpdater.Updater <int>((settings, index) => {
                settings.Gameplay.UnitSystem = EnumUtils.GetValues <UnitSystem>()[index];
                return(settings);
            }),
                currentIndex: () => EnumUtils.IndexOf(s().Gameplay.UnitSystem));
            VisualizeTrajectory = new GuiComponentDescriptor.Boolean(
                "visualize_trajectory",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.VisualizeTrajectory = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.VisualizeTrajectory);
            VisualizeAerodynamics = new GuiComponentDescriptor.Boolean(
                "visualize_aerodynamics",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.VisualizeAerodynamics = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.VisualizeAerodynamics);
            CoursesEnabled = new GuiComponentDescriptor.Boolean(
                "courses",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.CoursesEnabled = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.CoursesEnabled);
            IsRingCollisionOn = new GuiComponentDescriptor.Boolean(
                "ring_collision",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Gameplay.IsRingCollisionOn = value;
                return(settings);
            }),
                isChecked: () => s().Gameplay.IsRingCollisionOn);
            StallLimiterStrength = new GuiComponentDescriptor.Range(
                "stall_limiter_strength",
                minValue: 0f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.StallLimiterStrength = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.StallLimiterStrength,
                updateDisplayValue: (descriptor, str) => GuiComponentDescriptor.DisplayPercentage(s().Gameplay.StallLimiterStrength, str),
                stepSize: 0.01f);
            RollLimiterStrength = new GuiComponentDescriptor.Range(
                "roll_limiter_strength",
                minValue: 0f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.RollLimiterStrength = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.RollLimiterStrength,
                updateDisplayValue: (descriptor, str) => GuiComponentDescriptor.DisplayPercentage(s().Gameplay.RollLimiterStrength, str),
                stepSize: 0.01f);
            PitchAttitude = new GuiComponentDescriptor.Range(
                "pitch_attitude",
                minValue: -1f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                settings.Gameplay.PitchAttitude = value;
                return(settings);
            }),
                currentValue: () => s().Gameplay.PitchAttitude,
                updateDisplayValue: (descriptor, str) => GuiComponentDescriptor.DisplayNumber(s().Gameplay.PitchAttitude, str, decimalPlaces: 1),
                stepSize: 0.1f);
        }
Esempio n. 6
0
        public AudioSettingsViewModel(GameSettingsUpdater settingsUpdater)
        {
            Func <GameSettings> s = () => settingsUpdater.CurrentSettings;

            SoundEffectVolume = new GuiComponentDescriptor.Range(
                "sound_effect_volume",
                minValue: 0f,
                maxValue: 1f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                if (!settings.Audio.IsMuted)
                {
                    settings.Audio.SoundEffectsVolume = value;
                }
                return(settings);
            }),
                currentValue: () => s().Audio.SoundEffectsVolume,
                updateDisplayValue: (descriptor, str) => {
                if (s().Audio.IsMuted)
                {
                    descriptor.IsEnabled = false;
                    str.Append("─");     // Utf-8 char: &#x2500;
                }
                else
                {
                    descriptor.IsEnabled = true;
                    GuiComponentDescriptor.DisplayPercentage(s().Audio.SoundEffectsVolume, str);
                }
            },
                stepSize: 0.02f);
            MusicVolume = new GuiComponentDescriptor.Range(
                "music_volume",
                minValue: 0f,
                maxValue: 0.7f,
                updateValue: settingsUpdater.Updater <float>((settings, value) => {
                if (!settings.Audio.IsMuted)
                {
                    settings.Audio.MusicVolume = value;
                }
                return(settings);
            }),
                currentValue: () => s().Audio.MusicVolume,
                stepSize: 0.02f,
                updateDisplayValue: (descriptor, str) => {
                if (s().Audio.IsMuted)
                {
                    descriptor.IsEnabled = false;
                    str.Append("─");     // Utf-8 char: &#x2500;
                }
                else
                {
                    descriptor.IsEnabled      = true;
                    var musicVolumePercentage = Mathf.InverseLerp(descriptor.MinValue, descriptor.MaxValue,
                                                                  s().Audio.MusicVolume);
                    GuiComponentDescriptor.DisplayPercentage(musicVolumePercentage, str);
                }
            });
            Mute = new GuiComponentDescriptor.Boolean(
                "mute",
                updateValue: settingsUpdater.Updater <bool>((settings, value) => {
                settings.Audio.IsMuted = value;
                return(settings);
            }),
                isChecked: () => s().Audio.IsMuted);
        }
 public InputSettingsViewModel(GameSettingsUpdater settingsUpdater) {
     Func<GameSettings> s = () => settingsUpdater.CurrentSettings;
     WingsuitMouseSensitivity = new GuiComponentDescriptor.Range(
         "wingsuit_mouse_sensitivity",
         minValue: 0.1f,
         maxValue: 10.00f,
         updateValue: settingsUpdater.Updater<float>((settings, value) => {
             settings.Input.WingsuitMouseSensitivity = value;    
             return settings;
         }),
         currentValue: () => s().Input.WingsuitMouseSensitivity,
         updateDisplayValue: (descriptor, str) => {
             GuiComponentDescriptor.DisplayNumber(s().Input.WingsuitMouseSensitivity, str, decimalPlaces: 2);
         },
         stepSize: 0.01f);
     ParachuteMouseSensitivity = new GuiComponentDescriptor.Range(
         "chute_mouse_sensitivity",
         minValue: 0.1f,
         maxValue: 10f,
         updateValue: settingsUpdater.Updater<float>((settings, value) => {
             settings.Input.ParachuteMouseSensitivity = value;    
             return settings;
         }),
         currentValue: () => s().Input.ParachuteMouseSensitivity,
         updateDisplayValue: (descriptor, str) => {
             GuiComponentDescriptor.DisplayNumber(s().Input.ParachuteMouseSensitivity, str, decimalPlaces: 2);
         },
         stepSize: 0.01f);
     InputSpeedScaling = new GuiComponentDescriptor.Range(
         "input_speed_scaling",
         minValue: 0f,
         maxValue: 1f,
         updateValue: settingsUpdater.Updater<float>((settings, value) => {
             settings.Input.InputSpeedScaling = value;    
             return settings;
         }),
         currentValue: () => s().Input.InputSpeedScaling,
         updateDisplayValue: (descriptor, str) => {
             GuiComponentDescriptor.DisplayNumber(s().Input.InputSpeedScaling, str, decimalPlaces: 2);
         },
         stepSize: 0.01f);
     InputGamma = new GuiComponentDescriptor.Range(
         "input_gamma",
         minValue: 1f,
         maxValue: 3f,
         updateValue: settingsUpdater.Updater<float>((settings, value) => {
             settings.Input.InputGamma = value;    
             return settings;
         }),
         currentValue: () => s().Input.InputGamma,
         updateDisplayValue: (descriptor, str) => {
             GuiComponentDescriptor.DisplayNumber(s().Input.InputGamma, str, decimalPlaces: 2);
         },
         stepSize: 0.01f);
     JoystickDeadzone = new GuiComponentDescriptor.Range(
         "joystick_deadzone",
         minValue: 0f,
         maxValue: 0.99f,
         updateValue: settingsUpdater.Updater<float>((settings, value) => {
             settings.Input.JoystickDeadzone = value;    
             return settings;
         }),
         currentValue: () => s().Input.JoystickDeadzone,
         updateDisplayValue: (descriptor, str) => {
             GuiComponentDescriptor.DisplayNumber(s().Input.JoystickDeadzone, str, decimalPlaces: 2);
         },
         stepSize: 0.01f);
     var inputDefaults = EnumUtils.GetValues<InputDefaults>().ToList();
     inputDefaults.Remove(InputDefaults.XInput);
     RestoreInputDefaults = new GuiComponentDescriptor.List(
         "defaults",
         inputDefaults.Select(e => GuiComponentDescriptor.GetEnumString(e)).ToArray(),
         updateIndex: index => {
             var unappliedSettings = settingsUpdater.UnappliedSettings;
             unappliedSettings.InputDefaults = inputDefaults[index];
             settingsUpdater.UnappliedSettings = unappliedSettings;
         },
         currentIndex: () => {
             var unappliedSettings = settingsUpdater.UnappliedSettings;
             return inputDefaults.IndexOf(unappliedSettings.InputDefaults);
         });
 }