using System; using System.Collections.Generic; using UnityEngine; namespace DanroJump.Settings { /// /// Предпочитаемый способ отображения настройки в сервисном UI. /// public enum ServiceSettingDisplayMode { Auto, Toggle, Slider, Stepper, TextInput, Button, OptionPicker } /// /// Описание одной сервисной настройки: ключ, UI-метаданные, тип, дефолт и ограничения. /// [Serializable] public sealed class ServiceSettingDefinition { [SerializeField] private string key; [SerializeField] private string displayName; [SerializeField] [TextArea] private string description; [SerializeField] private string group = "General"; [SerializeField] private bool shownInServiceMenu = true; [SerializeField] private bool exposedForExternalChanges; [SerializeField] private ServiceSettingValueType valueType; [SerializeField] private ServiceSettingDisplayMode displayMode = ServiceSettingDisplayMode.Auto; [Header("Default values")] [SerializeField] private bool defaultBool = true; [SerializeField] private int defaultInt; [SerializeField] private float defaultFloat = 1f; [SerializeField] private string defaultString = ""; [SerializeField] private int defaultOptionIndex; [Header("Ranges")] [SerializeField] private int minInt; [SerializeField] private int maxInt = 10; [SerializeField] private int intStep = 1; [SerializeField] private float minFloat; [SerializeField] private float maxFloat = 1f; [SerializeField] private float floatStep = 0.1f; [SerializeField] private bool displayFloatAsPercentage; [Header("Options")] [SerializeField] private List options = new(); [Header("Button")] [SerializeField] private string buttonText; [SerializeField] private string buttonData; [SerializeField] private Color buttonColor = Color.white; [SerializeField] private Sprite buttonSprite; /// /// Уникальный ключ настройки. /// public string Key => key; /// /// Название настройки для сервисного UI. /// public string DisplayName => displayName; /// /// Описание настройки для подсказок обслуживающему персоналу. /// public string Description => description; /// /// Группа настройки в сервисном меню. /// public string Group => group; /// /// Показывать ли настройку в сервисном меню. /// public bool ShownInServiceMenu => shownInServiceMenu; /// /// Можно ли менять настройку через внешний JSON. /// public bool ExposedForExternalChanges => exposedForExternalChanges; /// /// Тип значения настройки. /// public ServiceSettingValueType ValueType => valueType; /// /// Предпочитаемый вид UI-контрола для настройки. /// public ServiceSettingDisplayMode DisplayMode => displayMode; /// /// Минимальное int-значение с защитой от перепутанных границ. /// public int MinInt => Mathf.Min(minInt, maxInt); /// /// Максимальное int-значение с защитой от перепутанных границ. /// public int MaxInt => Mathf.Max(minInt, maxInt); /// /// Шаг изменения int-значения. /// public int IntStep => Mathf.Max(1, intStep); /// /// Минимальное float-значение с защитой от перепутанных границ. /// public float MinFloat => Mathf.Min(minFloat, maxFloat); /// /// Максимальное float-значение с защитой от перепутанных границ. /// public float MaxFloat => Mathf.Max(minFloat, maxFloat); /// /// Шаг изменения float-значения. /// public float FloatStep => Mathf.Max(0.0001f, floatStep); /// /// Отображать ли float-значение как проценты. /// public bool DisplayFloatAsPercentage => displayFloatAsPercentage; /// /// Список вариантов для option-настройки. /// public IReadOnlyList Options => options; /// /// Текст кнопки действия. Если не задан, UI использует название настройки. /// public string ButtonText => buttonText; /// /// Дополнительные данные кнопки: URL, имя окна, идентификатор команды или другая payload-строка. /// public string ButtonData => buttonData; /// /// Цвет кнопки действия, перенесенный из legacy-базы. /// public Color ButtonColor => buttonColor; /// /// Опциональный спрайт кнопки действия. /// public Sprite ButtonSprite => buttonSprite; /// /// Значение по умолчанию, собранное из полей под выбранный тип. /// public ServiceSettingValue DefaultValue => valueType switch { ServiceSettingValueType.Bool => ServiceSettingValue.Bool(defaultBool), ServiceSettingValueType.Int => ServiceSettingValue.Int(defaultInt), ServiceSettingValueType.Float => ServiceSettingValue.Float(defaultFloat), ServiceSettingValueType.String => ServiceSettingValue.String(defaultString), ServiceSettingValueType.Button => ServiceSettingValue.Button(), ServiceSettingValueType.Option => ServiceSettingValue.Option(GetDefaultOptionIndex()), _ => default }; /// /// Приводит входное значение к типу и диапазонам настройки. /// public ServiceSettingValue Sanitize(ServiceSettingValue value) { if (valueType == ServiceSettingValueType.Button) { return ServiceSettingValue.Button(); } if (value.type != valueType && !(valueType == ServiceSettingValueType.Option && value.type == ServiceSettingValueType.Int)) { return Sanitize(DefaultValue); } return valueType switch { ServiceSettingValueType.Bool => ServiceSettingValue.Bool(value.boolValue), ServiceSettingValueType.Int => ServiceSettingValue.Int(Mathf.Clamp(value.intValue, MinInt, MaxInt)), ServiceSettingValueType.Float => ServiceSettingValue.Float(Mathf.Clamp(value.floatValue, MinFloat, MaxFloat)), ServiceSettingValueType.String => ServiceSettingValue.String(value.stringValue), ServiceSettingValueType.Option => ServiceSettingValue.Option(SanitizeOptionIndex(value.intValue)), _ => DefaultValue }; } /// /// Возвращает безопасный индекс варианта по умолчанию. /// private int GetDefaultOptionIndex() { return SanitizeOptionIndex(defaultOptionIndex); } /// /// Ограничивает option-index доступным диапазоном. /// private int SanitizeOptionIndex(int index) { return options is { Count: > 0 } ? Mathf.Clamp(index, 0, options.Count - 1) : 0; } } }