using UnityEngine; [CreateAssetMenu(fileName = "New Stat Definition", menuName = "RiftMayhem/Stat Definition")] public class StatDefinition : ScriptableObject { [Header("Identity & Display")] [SerializeField] private string statKey = ""; [SerializeField] private string displayName = ""; [SerializeField] private string shortName = ""; [TextArea(2, 4)] [SerializeField] private string description = ""; [SerializeField] private Sprite icon = null; // Nullable by default [Header("Categorization")] [SerializeField] private StatCategory category = StatCategory.Damage; [SerializeField] private bool isPrimary = false; [SerializeField] private bool showInUI = true; [SerializeField] private bool showInTooltips = true; [Header("Item Generation")] [SerializeField] private bool canRollOnItems = true; [SerializeField] private float defaultWeight = 1f; [SerializeField] private bool canBeFlat = true; [SerializeField] private bool canBePercent = true; [Header("Value Settings")] [SerializeField] private float defaultBaseValue = 0f; [SerializeField] private float minValue = float.MinValue; [SerializeField] private float maxValue = float.MaxValue; [SerializeField] private bool roundToInteger = false; // Public read-only properties public string StatKey => statKey; public string DisplayName => displayName; public string ShortName => shortName; public string Description => description; public Sprite Icon => icon; // Can be null public StatCategory Category => category; public bool IsPrimary => isPrimary; public bool ShowInUI => showInUI; public bool ShowInTooltips => showInTooltips; public bool CanRollOnItems => canRollOnItems; public float DefaultWeight => defaultWeight; public bool CanBeFlat => canBeFlat; public bool CanBePercent => canBePercent; public float DefaultBaseValue => defaultBaseValue; public float MinValue => minValue; public float MaxValue => maxValue; public bool RoundToInteger => roundToInteger; // Validation in the editor private void OnValidate() { // Ensure statKey is not empty and follows naming conventions if (string.IsNullOrEmpty(statKey)) { statKey = name.Replace(" ", "").Replace("(", "").Replace(")", "").ToLower(); } // Ensure displayName defaults to a readable version of statKey if empty if (string.IsNullOrEmpty(displayName) && !string.IsNullOrEmpty(statKey)) { displayName = System.Text.RegularExpressions.Regex.Replace(statKey, "([a-z])([A-Z])", "$1 $2"); } // Ensure shortName defaults to displayName if empty if (string.IsNullOrEmpty(shortName) && !string.IsNullOrEmpty(displayName)) { shortName = displayName.Length > 8 ? displayName.Substring(0, 8) : displayName; } // Ensure at least one value type is allowed if (!canBeFlat && !canBePercent) { canBeFlat = true; } // Ensure min/max values make sense if (minValue > maxValue) { maxValue = minValue; } // Ensure default weight is positive if (defaultWeight < 0f) { defaultWeight = 0f; } } // Utility method to check if an icon exists public bool HasIcon => icon != null; // Utility method to get formatted display name with fallback public string GetDisplayName(bool useShort = false) { if (useShort && !string.IsNullOrEmpty(shortName)) return shortName; return !string.IsNullOrEmpty(displayName) ? displayName : statKey; } } public enum StatCategory { Attributes, // Cunning, Flow, Presence Damage, // AttackDamage, SpellDamage Offensive, // AttackSpeed, CritChance, CritDamage Resource, // MaxHealth, HealthRegen, MaxMana, ManaRegen Defensive, // Armor, MagicResistance, DodgeChance, BlockChance Utility, // AreaEffectiveness, CooldownReduction, MovementSpeed Misc // ReputationGainIncrease, GoldCostReduction }