// ───────────────────────────────────────────────────────────────────────────── // WLTableValue.cs — 표의 문자형 값(s_Value) 해석 (PD #898 · 2026-10-17) // // PD 원문: 「장비 옵션의 value는 문형으로 읽되, 숫자는 정수로, 소수점이 있으면 실수로, // 60.25%와 같이 %를 입력하면 해당 확률에 맞게 지정되도록 구현할 것.」 // // ■ 규칙 — "20" → 정수 20 · "1.5" → 실수 1.5 · "60.25%" → 확률(비율) 0.6025 · 빈칸 → 없음 // 앞뒤 공백 무시 · 앞의 '+' 허용("+20" = 20) · 소수점은 '.' 만(문화권 무관) · 읽지 못하면 없음(raw 는 남김) // ■ 쓰임 — 장비 옵션 표 s_Value · 스킬 표 s_Value1~5 · s_TriggerValue (같은 규칙) // ───────────────────────────────────────────────────────────────────────────── using System.Globalization; using UnityEngine; namespace WL.Data { public enum eTableValueKind { None, Int, Float, Percent } public struct WLTableValue { public eTableValueKind kind; public int intValue; // kind Int public float floatValue; // kind Float = 그 수 · kind Percent = 비율(60.25% → 0.6025) public string raw; public bool IsNone { get { return kind == eTableValueKind.None; } } /// 실수로 쓸 때 — 정수 · 실수는 그 수, 확률은 비율(0~1). public float AsFloat { get { return kind == eTableValueKind.Int ? intValue : floatValue; } } /// 정수로 쓸 때 — 실수 · 확률은 반올림. public int AsInt { get { return kind == eTableValueKind.Int ? intValue : Mathf.RoundToInt(floatValue); } } public static WLTableValue Parse(string s) { var v = new WLTableValue { raw = s }; if (string.IsNullOrEmpty(s)) return v; s = s.Trim(); bool percent = s.EndsWith("%"); if (percent) s = s.Substring(0, s.Length - 1).Trim(); if (s.StartsWith("+")) s = s.Substring(1).Trim(); if (s.Length == 0) return v; const NumberStyles kDecimal = NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint; // 지수 표기(1e3) 받지 않음 if (percent) { float p; if (float.TryParse(s, kDecimal, CultureInfo.InvariantCulture, out p)) { v.kind = eTableValueKind.Percent; v.floatValue = p / 100f; } return v; } int n; if (s.IndexOf('.') < 0 && int.TryParse(s, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out n)) { v.kind = eTableValueKind.Int; v.intValue = n; return v; } float f; if (float.TryParse(s, kDecimal, CultureInfo.InvariantCulture, out f)) { v.kind = eTableValueKind.Float; v.floatValue = f; } return v; } public override string ToString() { switch (kind) { case eTableValueKind.Int: return "정수 " + intValue; case eTableValueKind.Float: return "실수 " + floatValue.ToString("0.####", CultureInfo.InvariantCulture); case eTableValueKind.Percent: return "확률 " + floatValue.ToString("0.######", CultureInfo.InvariantCulture); default: return "없음" + (string.IsNullOrEmpty(raw) ? "" : "(읽지 못함: " + raw + ")"); } } } }